Commit 80be08cd authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Filesystem discard option now propagates to devices



the discard option is special, because it's both a filesystem and a
device option.

When set at the filesytsem level, it's supposed to propagate to (if set
persistently via sysfs) or override (if non persistently as a mount
option) the devices - that now works correctly.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 8d7b7ac3
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -1806,6 +1806,19 @@ struct discard_buckets_state {
	u64		discarded;
};

/*
 * This is needed because discard is both a filesystem option and a device
 * option, and mount options are supposed to apply to that mount and not be
 * persisted, i.e. if it's set as a mount option we can't propagate it to the
 * device.
 */
static inline bool discard_opt_enabled(struct bch_fs *c, struct bch_dev *ca)
{
	return test_bit(BCH_FS_discard_mount_opt_set, &c->flags)
		? c->opts.discard
		: ca->mi.discard;
}

static int bch2_discard_one_bucket(struct btree_trans *trans,
				   struct bch_dev *ca,
				   struct btree_iter *need_discard_iter,
@@ -1869,7 +1882,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
		s->discarded++;
		*discard_pos_done = iter.pos;

		if (ca->mi.discard && !c->opts.nochanges) {
		if (discard_opt_enabled(c, ca) && !c->opts.nochanges) {
			/*
			 * This works without any other locks because this is the only
			 * thread that removes items from the need_discard tree
+2 −1
Original line number Diff line number Diff line
@@ -627,7 +627,8 @@ struct bch_dev {
	x(topology_error)		\
	x(errors_fixed)			\
	x(errors_not_fixed)		\
	x(no_invalid_checks)
	x(no_invalid_checks)		\
	x(discard_mount_opt_set)	\

enum bch_fs_flags {
#define x(n)		BCH_FS_##n,
+3 −0
Original line number Diff line number Diff line
@@ -2172,6 +2172,9 @@ static int bch2_fs_get_tree(struct fs_context *fc)
	if (ret)
		goto err;

	if (opt_defined(opts, discard))
		set_bit(BCH_FS_discard_mount_opt_set, &c->flags);

	/* Some options can't be parsed until after the fs is started: */
	opts = bch2_opts_empty();
	ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf);
+9 −0
Original line number Diff line number Diff line
@@ -664,6 +664,15 @@ static ssize_t sysfs_opt_store(struct bch_fs *c,
	    c->copygc_thread)
		wake_up_process(c->copygc_thread);

	if (id == Opt_discard && !ca) {
		mutex_lock(&c->sb_lock);
		for_each_member_device(c, ca)
			opt->set_member(bch2_members_v2_get_mut(ca->disk_sb.sb, ca->dev_idx), v);

		bch2_write_super(c);
		mutex_unlock(&c->sb_lock);
	}

	ret = size;
err:
	up_write(&c->state_lock);