FAILED: patch "[PATCH] btrfs: Take trans lock before access running trans in" failed to apply to 4.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
998ac6d21cfd6efd58f5edf420bae8839dda9f2aMon Sep 17 00:00:00 2001
From: ethanwu <[email protected]>
Date: Sun, 29 Apr 2018 15:59:42 +0800
Subject: [PATCH] btrfs: Take trans lock before access running trans in
check_delayed_ref
In preivous patch:
Btrfs: kill trans in run_delalloc_nocow and btrfs_cross_ref_exist We avoid starting btrfs transaction and get this information from fs_info->running_transaction directly.
When accessing running_transaction in check_delayed_ref, there's a chance that current transaction will be freed by commit transaction after the NULL pointer check of running_transaction is passed.
After looking all the other places using fs_info->running_transaction, they are either protected by trans_lock or holding the transactions.
Fix this by using trans_lock and increasing the use_count.
fs/btrfs/extent-tree.c +7 -0
@@ -3142,7 +3142,11 @@ static noinline int check_delayed_ref(struct btrfs_root *root,struct rb_node *node;int ret =0 ; +spin_lock (&root->fs_info->trans_lock); cur_trans = root->fs_info->running_transaction; +if (cur_trans) +refcount_inc (&cur_trans->use_count); +spin_unlock (&root->fs_info->trans_lock);if (!cur_trans)return 0 ;
@@ -3151,6 +3155,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, head =btrfs_find_delayed_ref_head (delayed_refs, bytenr);if (!head) {spin_unlock (&delayed_refs->lock); +btrfs_put_transaction (cur_trans);return 0 ; }
@@ -3167,6 +3172,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root,mutex_lock (&head->mutex);mutex_unlock (&head->mutex);btrfs_put_delayed_ref_head (head); +btrfs_put_transaction (cur_trans);return -EAGAIN ; }spin_unlock (&delayed_refs->lock);
@@ -3199,6 +3205,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, }spin_unlock (&head->lock);mutex_unlock (&head->mutex); +btrfs_put_transaction (cur_trans);return ret; }
PATCH 1/1 btrfs: Take trans lock before access running trans in check_delayed_ref
commit 998ac6d21cfd6efd58f5edf420bae8839dda9f2a upstream
In preivous patch:
Btrfs: kill trans in run_delalloc_nocow and btrfs_cross_ref_exist We avoid starting btrfs transaction and get this information from fs_info->running_transaction directly.
When accessing running_transaction in check_delayed_ref, there's a chance that current transaction will be freed by commit transaction after the NULL pointer check of running_transaction is passed.
After looking all the other places using fs_info->running_transaction, they are either protected by trans_lock or holding the transactions.
Fix this by using trans_lock and increasing the use_count.
--- fs/btrfs/extent-tree.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/btrfs/extent-tree.c +7 -0
@@ -3171,7 +3171,11 @@ static noinline int check_delayed_ref(struct btrfs_root *root,struct btrfs_transaction *cur_trans;int ret =0 ; +spin_lock (&root->fs_info->trans_lock); cur_trans = root->fs_info->running_transaction; +if (cur_trans) +refcount_inc (&cur_trans->use_count); +spin_unlock (&root->fs_info->trans_lock);if (!cur_trans)return 0 ;
@@ -3180,6 +3184,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, head =btrfs_find_delayed_ref_head (delayed_refs, bytenr);if (!head) {spin_unlock (&delayed_refs->lock); +btrfs_put_transaction (cur_trans);return 0 ; }
@@ -3196,6 +3201,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root,mutex_lock (&head->mutex);mutex_unlock (&head->mutex);btrfs_put_delayed_ref (&head->node); +btrfs_put_transaction (cur_trans);return -EAGAIN ; }spin_unlock (&delayed_refs->lock);
@@ -3223,6 +3229,7 @@ static noinline int check_delayed_ref(struct btrfs_root *root, }spin_unlock (&head->lock);mutex_unlock (&head->mutex); +btrfs_put_transaction (cur_trans);return ret; }
Signature · 1 line
1.9.1
Greg KH
maintainerRe: [PATCH] btrfs: Take trans lock before access running trans in check_delayed_ref
Quoted 16 lines · ethanwu
commit
998ac6d21cfd6efd58f5edf420bae8839dda9f2aupstreamIn preivous patch:
Btrfs: kill trans inrun_delalloc_nocowandbtrfs_cross_ref_existWe avoid starting btrfs transaction and get this information fromfs_info->running_transactiondirectly.When accessing
running_transactionincheck_delayed_ref, there's a chance that current transaction will be freed by commit transaction after the NULL pointer check ofrunning_transactionis passed.After looking all the other places using
fs_info->running_transaction, they are either protected bytrans_lockor holding the transactions.Fix this by using
trans_lockand increasing theuse_count.
Quoted 7 lines
Fixes e4c3b2dcd144 ("Btrfs: kill trans in run_delalloc_nocow and btrfs_cross_ref_exist")CC [email protected] # 4.14+Signed-off-by ethanwu <[email protected]>Signed-off-by David Sterba <[email protected]>--- fs/btrfs/extent-tree.c | 7 +++++++ 1 file changed, 7 insertions(+)
Thanks for the backport, now queued up.
greg k-h