Support for 'pending changes'
There are some actions that modify global filesystem state but cannot be performed at the time of request, but rather later at the transaction commit time when the filesystem is in a known state.
The change can be requested from any context and is permanent after sync. This changes the semantics for the sysfs files that modify label or feature bits, but I think this does not break existing applications.
You can pull the series from
git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git dev/pending-changes
David Sterba (6):
btrfs: add support for processing pending changes
btrfs: do commit in sync_fs if there are pending changes
btrfs: switch inode_cache option handling to pending changes
btrfs: introduce pending action: commit
btrfs: move commit out of sysfs when changing features
btrfs: move commit out of sysfs when changing label
fs/btrfs/ctree.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- fs/btrfs/disk-io.c | 8 +++++--- fs/btrfs/inode-map.c | 2 +- fs/btrfs/super.c | 18 +++++++++++++----- fs/btrfs/sysfs.c | 34 +++++++++++++--------------------- fs/btrfs/transaction.c | 38 ++++++++++++++++++++++++++++++++------ fs/btrfs/transaction.h | 2 ++ 7 files changed, 115 insertions(+), 37 deletions(-)
Signature · 1 line
1.8.4.5
PATCH 1/6 btrfs: add support for processing pending changes
There are some actions that modify global filesystem state but cannot be performed at the time of request, but later at the transaction commit time when the filesystem is in a known state.
For example enabling new incompat features on-the-fly or issuing transaction commit from unsafe contexts (sysfs handlers).
--- fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/disk-io.c | 6 ++++++ fs/btrfs/transaction.c | 16 ++++++++++++++++ fs/btrfs/transaction.h | 2 ++ 4 files changed, 69 insertions(+)
fs/btrfs/ctree.h +45 -0
@@ -1402,6 +1402,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;/*
@@ -2103,6 +2108,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)) \
@@ -2118,6 +2124,45 @@ struct btrfs_ioctl_defrag_range_args { }/* +* 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_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 */ #define BTRFS_INODE_NODATASUM (1 << 0)
fs/btrfs/disk-io.c +6 -0
@@ -2834,6 +2834,12 @@ retry_root_backup: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 )) { ret = btrfsic_mount(tree_root, fs_devices,
fs/btrfs/transaction.c +16 -0
@@ -1850,6 +1850,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,else btrfs_clear_opt (root->fs_info->mount_opt,INODE_MAP_CACHE ); +btrfs_apply_pending_changes (root->fs_info); +/* commit_fs_roots gets rid of all the tree log roots, it is now * safe to free the root of tree log roots */
@@ -2019,3 +2021,17 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root)return (ret <0 ) ?0 :1 ; } + +void btrfs_apply_pending_changes (struct btrfs_fs_info *fs_info) +{ +unsigned long prev; +unsigned long bit; + + prev =cmpxchg (&fs_info->pending_changes,0 ,0 ); +if (!prev) +return ; + +if (prev) +btrfs_warn (fs_info, +"unknown pending changes left 0x%lx, ignoring" , prev); +}
fs/btrfs/transaction.h +2 -0
@@ -170,4 +170,6 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,int btrfs_transaction_blocked (struct btrfs_fs_info *info);int btrfs_transaction_in_commit (struct btrfs_fs_info *info);void btrfs_put_transaction (struct btrfs_transaction *transaction); +void btrfs_apply_pending_changes (struct btrfs_fs_info *fs_info); +#endif
Signature · 1 line
1.8.4.5
Re: [PATCH 1/6] btrfs: add support for processing pending changes
-------- Original Message --------
Subject: [PATCH 1/6] btrfs: add support for processing pending changes
From: David Sterba <[email protected]>
To: <[email protected]>
Date: 2014年11月14日 18:33
Quoted 116 lines
There are some actions that modify global filesystem state but cannot be performed at the time of request, but later at the transaction commit time when the filesystem is in a known state.
For example enabling new incompat features on-the-fly or issuing transaction commit from unsafe contexts (sysfs handlers).
Signed-off-by David Sterba <[email protected]>--- fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/disk-io.c | 6 ++++++ fs/btrfs/transaction.c | 16 ++++++++++++++++ fs/btrfs/transaction.h | 2 ++ 4 files changed, 69 insertions(+)fs/btrfs/ctree.h +45
-0@@ -1402,6 +1402,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;/* @@ -2103,6 +2108,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)) \@@ -2118,6 +2124,45 @@ struct btrfs_ioctl_defrag_range_args { }/* +* 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_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 */ #define BTRFS_INODE_NODATASUM (1 << 0)fs/btrfs/disk-io.c +6
-0@@ -2834,6 +2834,12 @@ retry_root_backup: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 )) { ret = btrfsic_mount(tree_root, fs_devices,fs/btrfs/transaction.c +2
-0@@ -1850,6 +1850,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,else btrfs_clear_opt (root->fs_info->mount_opt,INODE_MAP_CACHE ); +btrfs_apply_pending_changes (root->fs_info); +/* commit_fs_roots gets rid of all the tree log roots, it is now * safe to free the root of tree log roots */
fs/btrfs/transaction.c int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root) · line 2030
Quoted 10 lines
fs/btrfs/transaction.c +7
-0@@ -2019,3 +2021,17 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root)return (ret <0 ) ?0 :1 ; } + +void btrfs_apply_pending_changes (struct btrfs_fs_info *fs_info) +{ +unsigned long prev; +unsigned long bit; + + prev =cmpxchg (&fs_info->pending_changes,0 ,0 );
Another HUGE problem here.
cmpxchg will only change the pending_changes to 0 if it's already 0. If it not 0, it will not change pending_changes to 0.
So pending_changes will always be non-zero if set_pending....
Thanks,
Qu
Quoted 18 lines
fs/btrfs/transaction.c +7
-0+if (!prev) +return ; + +if (prev) +btrfs_warn (fs_info, +"unknown pending changes left 0x%lx, ignoring" , prev); +}fs/btrfs/transaction.h +2
-0@@ -170,4 +170,6 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,int btrfs_transaction_blocked (struct btrfs_fs_info *info);int btrfs_transaction_in_commit (struct btrfs_fs_info *info);void btrfs_put_transaction (struct btrfs_transaction *transaction); +void btrfs_apply_pending_changes (struct btrfs_fs_info *fs_info); +#endif
PATCH 2/6 btrfs: do commit in sync_fs if there are pending changes
In reply to David SterbaIf a pending change is requested, it's not processed unless there is a transaction commit about to happen, not even after sync or SYNC_FS ioctl. For example a remount that toggles the inode_cache option will not take effect after sync on a quiescent filesystem.
--- fs/btrfs/super.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/btrfs/super.c +11 -3
@@ -993,9 +993,17 @@ 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 ) -return 0 ; -return PTR_ERR (trans); +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); }
Signature · 1 line
1.8.4.5
Re: [PATCH 2/6] btrfs: do commit in sync_fs if there are pending changes
Quoted 19 lines · David Sterba
If a pending change is requested, it's not processed unless there is a transaction commit about to happen, not even after sync or
SYNC_FSioctl. For example a remount that toggles theinode_cacheoption will not take effect after sync on a quiescent filesystem.Signed-off-by David Sterba <[email protected]>--- fs/btrfs/super.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)fs/btrfs/super.c +0
-1@@ -993,9 +993,17 @@ 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 )
fs/btrfs/super.c int btrfs_sync_fs(struct super_block *sb, int wait) · line 1003
Quoted 10 lines
fs/btrfs/super.c +8
-2-return 0 ; -return PTR_ERR (trans); +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 );
Missing check for IS_ERR(trans)
The rest looks good.
Thanks
Quoted 13 lines
fs/btrfs/super.c +3
-1+ }else { +return PTR_ERR (trans); + } }return btrfs_commit_transaction (trans, root); } --1.8.4.5
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 5 lines
Filipe David Manana, "Reasonable men adapt themselves to the world. Unreasonable men adapt the world to themselves. That's why all progress depends on unreasonable men."
PATCH v2 2/6 btrfs: do commit in sync_fs if there are pending changes
In reply to David SterbaIf a pending change is requested, it's not processed unless there is a transaction commit about to happen, not even after sync or SYNC_FS ioctl. For example a remount that toggles the inode_cache option will not take effect after sync on a quiescent filesystem.
---
v2: catch error from btrfs_start_transaction
fs/btrfs/super.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/btrfs/super.c +11 -3
@@ -993,9 +993,17 @@ 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 ) -return 0 ; -return PTR_ERR (trans); +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 ); + } +if (IS_ERR (trans)) +return PTR_ERR (trans); }return btrfs_commit_transaction (trans, root); }
Signature · 1 line
2.1.3
Re: [PATCH 2/6 v2] btrfs: do commit in sync_fs if there are pending changes
Quoted 9 lines · David Sterba
If a pending change is requested, it's not processed unless there is a transaction commit about to happen, not even after sync or
SYNC_FSioctl. For example a remount that toggles theinode_cacheoption will not take effect after sync on a quiescent filesystem.Signed-off-by David Sterba <[email protected]>---
v2: catch error from
btrfs_start_transaction
V2 didn't make it to 3.19:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6b5fe46dfa52441f49c7432b1c1b1cb767834708
Quoted 36 lines
fs/btrfs/super.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)fs/btrfs/super.c +11
-4@@ -993,9 +993,17 @@ 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 ) -return 0 ; -return PTR_ERR (trans); +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 ); + } +if (IS_ERR (trans)) +return PTR_ERR (trans); }return btrfs_commit_transaction (trans, root); } --2.1.3
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 5 lines
Filipe David Manana, "Reasonable men adapt themselves to the world. Unreasonable men adapt the world to themselves. That's why all progress depends on unreasonable men."
PATCH 3/6 btrfs: switch inode_cache option handling to pending changes
In reply to David SterbaThe pending mount option(s) now share namespace and bits with the normal options, and the existing one for (inode_cache) is unset unconditionally at each transaction commit.
Introduce a separate namespace for pending changes and enhance the descriptions of the intended change to use separate bits for each action.
--- fs/btrfs/ctree.h | 4 +++- fs/btrfs/disk-io.c | 4 ---- fs/btrfs/inode-map.c | 2 +- fs/btrfs/super.c | 4 ++-- fs/btrfs/transaction.c | 19 ++++++++++++------- 5 files changed, 18 insertions(+), 15 deletions(-)
fs/btrfs/ctree.h +3 -1
@@ -2098,7 +2098,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)
@@ -2131,6 +2130,9 @@ struct btrfs_ioctl_defrag_range_args {* transaction commit) */ +#define BTRFS_PENDING_SET_INODE_MAP_CACHE (0) +#define BTRFS_PENDING_CLEAR_INODE_MAP_CACHE (1) +#define btrfs_test_pending (info, opt) \ test_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)#define btrfs_set_pending (info, opt) \
fs/btrfs/disk-io.c +0 -4
@@ -2830,10 +2830,6 @@ retry_root_backup: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
fs/btrfs/inode-map.c +1 -1
@@ -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" ); } }
fs/btrfs/super.c +2 -2
@@ -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:
fs/btrfs/transaction.c +12 -7
@@ -1842,14 +1842,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, }/* -* Since the transaction is done, we should set the inode map cache flag -* before any other comming transaction. +* Since the transaction is done, we can apply the pending changes +* before the next transaction. */ -if (btrfs_test_opt (root,CHANGE_INODE_CACHE )) -btrfs_set_opt (root->fs_info->mount_opt,INODE_MAP_CACHE ); -else -btrfs_clear_opt (root->fs_info->mount_opt,INODE_MAP_CACHE ); -btrfs_apply_pending_changes (root->fs_info);/* commit_fs_roots gets rid of all the tree log roots, it is now
@@ -2031,6 +2026,16 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info)if (!prev)return ; + bit =1 <<BTRFS_PENDING_SET_INODE_MAP_CACHE ; +if (prev & bit) +btrfs_set_opt (fs_info->mount_opt,INODE_MAP_CACHE ); + prev &= ~bit; + + bit =1 <<BTRFS_PENDING_CLEAR_INODE_MAP_CACHE ; +if (prev & bit) +btrfs_clear_opt (fs_info->mount_opt,INODE_MAP_CACHE ); + prev &= ~bit; +if (prev)btrfs_warn (fs_info,"unknown pending changes left 0x%lx, ignoring" , prev);
Signature · 1 line
1.8.4.5
PATCH 4/6 btrfs: introduce pending action: commit
In reply to David SterbaIn some contexts, like in sysfs handlers, we don't want to trigger a transaction commit. It's a heavy operation, we don't know what external locks may be taken. Instead, make it possible to finish the operation through sync syscall or SYNC_FS ioctl.
--- fs/btrfs/ctree.h | 1 + fs/btrfs/transaction.c | 5 +++++ 2 files changed, 6 insertions(+)
fs/btrfs/ctree.h +1 -0
@@ -2132,6 +2132,7 @@ struct btrfs_ioctl_defrag_range_args {#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)
fs/btrfs/transaction.c +5 -0
@@ -2036,6 +2036,11 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info)btrfs_clear_opt (fs_info->mount_opt,INODE_MAP_CACHE ); prev &= ~bit; + bit =1 <<BTRFS_PENDING_COMMIT ; +if (prev & bit) +btrfs_debug (fs_info,"pending commit done" ); + prev &= ~bit; +if (prev)btrfs_warn (fs_info,"unknown pending changes left 0x%lx, ignoring" , prev);
Signature · 1 line
1.8.4.5
PATCH 5/6 btrfs: move commit out of sysfs when changing features
In reply to David Sterba--- fs/btrfs/sysfs.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
fs/btrfs/sysfs.c +5 -8
@@ -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; }
Signature · 1 line
1.8.4.5
PATCH 6/6 btrfs: move commit out of sysfs when changing label
In reply to David Sterba--- fs/btrfs/sysfs.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
fs/btrfs/sysfs.c +8 -13
@@ -369,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 )
@@ -386,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);
Signature · 1 line
1.8.4.5