Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad27c0da authored by Chris Mason's avatar Chris Mason
Browse files

Merge branch 'dev/pending-changes' of...

Merge branch 'dev/pending-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus
parents b38ef71c a6f69dc8
Loading
Loading
Loading
Loading
+49 −1
Original line number Diff line number Diff line
@@ -1407,6 +1407,11 @@ struct btrfs_fs_info {
	 */
	u64 last_trans_log_full_commit;
	unsigned long mount_opt;
	/*
	 * Track requests for actions that need to be done during transaction
	 * commit (like for some mount options).
	 */
	unsigned long pending_changes;
	unsigned long compress_type:4;
	int commit_interval;
	/*
@@ -2098,7 +2103,6 @@ struct btrfs_ioctl_defrag_range_args {
#define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21)
#define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR	(1 << 22)
#define BTRFS_MOUNT_RESCAN_UUID_TREE	(1 << 23)
#define	BTRFS_MOUNT_CHANGE_INODE_CACHE	(1 << 24)

#define BTRFS_DEFAULT_COMMIT_INTERVAL	(30)
#define BTRFS_DEFAULT_MAX_INLINE	(8192)
@@ -2108,6 +2112,7 @@ struct btrfs_ioctl_defrag_range_args {
#define btrfs_raw_test_opt(o, opt)	((o) & BTRFS_MOUNT_##opt)
#define btrfs_test_opt(root, opt)	((root)->fs_info->mount_opt & \
					 BTRFS_MOUNT_##opt)

#define btrfs_set_and_info(root, opt, fmt, args...)			\
{									\
	if (!btrfs_test_opt(root, opt))					\
@@ -2122,6 +2127,49 @@ struct btrfs_ioctl_defrag_range_args {
	btrfs_clear_opt(root->fs_info->mount_opt, opt);			\
}

/*
 * Requests for changes that need to be done during transaction commit.
 *
 * Internal mount options that are used for special handling of the real
 * mount options (eg. cannot be set during remount and have to be set during
 * transaction commit)
 */

#define BTRFS_PENDING_SET_INODE_MAP_CACHE	(0)
#define BTRFS_PENDING_CLEAR_INODE_MAP_CACHE	(1)
#define BTRFS_PENDING_COMMIT			(2)

#define btrfs_test_pending(info, opt)	\
	test_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
#define btrfs_set_pending(info, opt)	\
	set_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
#define btrfs_clear_pending(info, opt)	\
	clear_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)

/*
 * Helpers for setting pending mount option changes.
 *
 * Expects corresponding macros
 * BTRFS_PENDING_SET_ and CLEAR_ + short mount option name
 */
#define btrfs_set_pending_and_info(info, opt, fmt, args...)            \
do {                                                                   \
       if (!btrfs_raw_test_opt((info)->mount_opt, opt)) {              \
               btrfs_info((info), fmt, ##args);                        \
               btrfs_set_pending((info), SET_##opt);                   \
               btrfs_clear_pending((info), CLEAR_##opt);               \
       }                                                               \
} while(0)

#define btrfs_clear_pending_and_info(info, opt, fmt, args...)          \
do {                                                                   \
       if (btrfs_raw_test_opt((info)->mount_opt, opt)) {               \
               btrfs_info((info), fmt, ##args);                        \
               btrfs_set_pending((info), CLEAR_##opt);                 \
               btrfs_clear_pending((info), SET_##opt);                 \
       }                                                               \
} while(0)

/*
 * Inode flags
 */
+5 −3
Original line number Diff line number Diff line
@@ -2830,9 +2830,11 @@ int open_ctree(struct super_block *sb,
		btrfs_set_opt(fs_info->mount_opt, SSD);
	}

	/* Set the real inode map cache flag */
	if (btrfs_test_opt(tree_root, CHANGE_INODE_CACHE))
		btrfs_set_opt(tree_root->fs_info->mount_opt, INODE_MAP_CACHE);
	/*
	 * Mount does not set all options immediatelly, we can do it now and do
	 * not have to wait for transaction commit
	 */
	btrfs_apply_pending_changes(fs_info);

#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
	if (btrfs_test_opt(tree_root, CHECK_INTEGRITY)) {
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ static void start_caching(struct btrfs_root *root)
			  root->root_key.objectid);
	if (IS_ERR(tsk)) {
		btrfs_warn(root->fs_info, "failed to start inode caching task");
		btrfs_clear_and_info(root, CHANGE_INODE_CACHE,
		btrfs_clear_pending_and_info(root->fs_info, INODE_MAP_CACHE,
				"disabling inode map caching");
	}
}
+13 −5
Original line number Diff line number Diff line
@@ -642,11 +642,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
					     "disabling disk space caching");
			break;
		case Opt_inode_cache:
			btrfs_set_and_info(root, CHANGE_INODE_CACHE,
			btrfs_set_pending_and_info(info, INODE_MAP_CACHE,
					   "enabling inode map caching");
			break;
		case Opt_noinode_cache:
			btrfs_clear_and_info(root, CHANGE_INODE_CACHE,
			btrfs_clear_pending_and_info(info, INODE_MAP_CACHE,
					     "disabling inode map caching");
			break;
		case Opt_clear_cache:
@@ -993,10 +993,18 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
	trans = btrfs_attach_transaction_barrier(root);
	if (IS_ERR(trans)) {
		/* no transaction, don't bother */
		if (PTR_ERR(trans) == -ENOENT)
		if (PTR_ERR(trans) == -ENOENT) {
			/*
			 * Exit unless we have some pending changes
			 * that need to go through commit
			 */
			if (fs_info->pending_changes == 0)
				return 0;
			trans = btrfs_start_transaction(root, 0);
		} else {
			return PTR_ERR(trans);
		}
	}
	return btrfs_commit_transaction(trans, root);
}

+13 −21
Original line number Diff line number Diff line
@@ -111,7 +111,6 @@ static ssize_t btrfs_feature_attr_store(struct kobject *kobj,
{
	struct btrfs_fs_info *fs_info;
	struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
	struct btrfs_trans_handle *trans;
	u64 features, set, clear;
	unsigned long val;
	int ret;
@@ -153,10 +152,6 @@ static ssize_t btrfs_feature_attr_store(struct kobject *kobj,
	btrfs_info(fs_info, "%s %s feature flag",
		   val ? "Setting" : "Clearing", fa->kobj_attr.attr.name);

	trans = btrfs_start_transaction(fs_info->fs_root, 0);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	spin_lock(&fs_info->super_lock);
	features = get_features(fs_info, fa->feature_set);
	if (val)
@@ -166,9 +161,11 @@ static ssize_t btrfs_feature_attr_store(struct kobject *kobj,
	set_features(fs_info, fa->feature_set, features);
	spin_unlock(&fs_info->super_lock);

	ret = btrfs_commit_transaction(trans, fs_info->fs_root);
	if (ret)
		return ret;
	/*
	 * We don't want to do full transaction commit from inside sysfs
	 */
	btrfs_set_pending(fs_info, COMMIT);
	wake_up_process(fs_info->transaction_kthread);

	return count;
}
@@ -372,9 +369,6 @@ static ssize_t btrfs_label_store(struct kobject *kobj,
				 const char *buf, size_t len)
{
	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
	struct btrfs_trans_handle *trans;
	struct btrfs_root *root = fs_info->fs_root;
	int ret;
	size_t p_len;

	if (fs_info->sb->s_flags & MS_RDONLY)
@@ -389,20 +383,18 @@ static ssize_t btrfs_label_store(struct kobject *kobj,
	if (p_len >= BTRFS_LABEL_SIZE)
		return -EINVAL;

	trans = btrfs_start_transaction(root, 0);
	if (IS_ERR(trans))
		return PTR_ERR(trans);

	spin_lock(&root->fs_info->super_lock);
	spin_lock(&fs_info->super_lock);
	memset(fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE);
	memcpy(fs_info->super_copy->label, buf, p_len);
	spin_unlock(&root->fs_info->super_lock);
	ret = btrfs_commit_transaction(trans, root);
	spin_unlock(&fs_info->super_lock);

	if (!ret)
		return len;
	/*
	 * We don't want to do full transaction commit from inside sysfs
	 */
	btrfs_set_pending(fs_info, COMMIT);
	wake_up_process(fs_info->transaction_kthread);

	return ret;
	return len;
}
BTRFS_ATTR_RW(label, btrfs_label_show, btrfs_label_store);

Loading