summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/discard.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/discard.c')
-rw-r--r--fs/btrfs/discard.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/btrfs/discard.c b/fs/btrfs/discard.c
index cb9a23217ec6..99663641abf4 100644
--- a/fs/btrfs/discard.c
+++ b/fs/btrfs/discard.c
@@ -343,6 +343,35 @@ bool btrfs_run_discard_work(struct btrfs_discard_ctl *discard_ctl)
}
/**
+ * btrfs_discard_update_discardable - propagate discard counters
+ * @block_group: block_group of interest
+ * @ctl: free_space_ctl of @block_group
+ *
+ * This propagates deltas of counters up to the discard_ctl. It maintains a
+ * current counter and a previous counter passing the delta up to the global
+ * stat. Then the current counter value becomes the previous counter value.
+ */
+void btrfs_discard_update_discardable(struct btrfs_block_group *block_group,
+ struct btrfs_free_space_ctl *ctl)
+{
+ struct btrfs_discard_ctl *discard_ctl;
+ s32 extents_delta;
+
+ if (!block_group || !btrfs_test_opt(block_group->fs_info, DISCARD_ASYNC))
+ return;
+
+ discard_ctl = &block_group->fs_info->discard_ctl;
+
+ extents_delta = ctl->discardable_extents[BTRFS_STAT_CURR] -
+ ctl->discardable_extents[BTRFS_STAT_PREV];
+ if (extents_delta) {
+ atomic_add(extents_delta, &discard_ctl->discardable_extents);
+ ctl->discardable_extents[BTRFS_STAT_PREV] =
+ ctl->discardable_extents[BTRFS_STAT_CURR];
+ }
+}
+
+/**
* btrfs_discard_punt_unused_bgs_list - punt unused_bgs list to discard lists
* @fs_info: fs_info of interest
*
@@ -423,6 +452,8 @@ void btrfs_discard_init(struct btrfs_fs_info *fs_info)
for (i = 0; i < BTRFS_NR_DISCARD_LISTS; i++)
INIT_LIST_HEAD(&discard_ctl->discard_list[i]);
+
+ atomic_set(&discard_ctl->discardable_extents, 0);
}
void btrfs_discard_cleanup(struct btrfs_fs_info *fs_info)