45NhhVPko5txKuuzDPqhyK changeset

Changeset633566663532 (b)
ParentNone (a)
ab
0+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
0+index 3f180b857e20..eea7d68fdcf2 100644
0+--- a/fs/btrfs/inode.c
0++++ b/fs/btrfs/inode.c
0+@@ -2928,7 +2928,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
0+        int compress_type = 0;
0+        int ret = 0;
0+        u64 logical_len = ordered_extent->len;
0+-       bool nolock;
0++       bool nolock = false;
0+        bool truncated = false;
0+        bool range_locked = false;
0+        bool clear_new_delalloc_bytes = false;
0+@@ -2939,7 +2939,16 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
0+            !test_bit(BTRFS_ORDERED_DIRECT, &ordered_extent->flags))
0+                clear_new_delalloc_bytes = true;
0+ 
0+-       nolock = btrfs_is_free_space_inode(BTRFS_I(inode));
0++       if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
0++               nolock = true;
0++       } else {
0++               spin_lock(&fs_info->trans_lock);
0++               if (fs_info->running_transaction &&
0++                   (fs_info->running_transaction->state ==
0++                    TRANS_STATE_COMMIT_START))
0++                       nolock = true;
0++               spin_unlock(&fs_info->trans_lock);
0++       }
0+ 
0+        if (test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags)) {
0+                ret = -EIO;
0+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
0+index acdad6d658f5..42d756267e9a 100644
0+--- a/fs/btrfs/transaction.c
0++++ b/fs/btrfs/transaction.c
0+@@ -1888,17 +1888,8 @@ static void btrfs_cleanup_pending_block_groups(struct btrfs_trans_handle *trans)
0+ 
0+ static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
0+ {
0+-       /*
0+-        * We use writeback_inodes_sb here because if we used
0+-        * btrfs_start_delalloc_roots we would deadlock with fs freeze.
0+-        * Currently are holding the fs freeze lock, if we do an async flush
0+-        * we'll do btrfs_join_transaction() and deadlock because we need to
0+-        * wait for the fs freeze lock.  Using the direct flushing we benefit
0+-        * from already being in a transaction and our join_transaction doesn't
0+-        * have to re-take the fs freeze lock.
0+-        */
0+        if (btrfs_test_opt(fs_info, FLUSHONCOMMIT))
0+-               writeback_inodes_sb(fs_info->sb, WB_REASON_SYNC);
0++               return btrfs_start_delalloc_roots(fs_info, 1, -1);
0+        return 0;
0+ }
0+ 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
--- Revision None
+++ Revision 633566663532
@@ -0,0 +1,54 @@
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 3f180b857e20..eea7d68fdcf2 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2928,7 +2928,7 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
+ int compress_type = 0;
+ int ret = 0;
+ u64 logical_len = ordered_extent->len;
+- bool nolock;
++ bool nolock = false;
+ bool truncated = false;
+ bool range_locked = false;
+ bool clear_new_delalloc_bytes = false;
+@@ -2939,7 +2939,16 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
+ !test_bit(BTRFS_ORDERED_DIRECT, &ordered_extent->flags))
+ clear_new_delalloc_bytes = true;
+
+- nolock = btrfs_is_free_space_inode(BTRFS_I(inode));
++ if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
++ nolock = true;
++ } else {
++ spin_lock(&fs_info->trans_lock);
++ if (fs_info->running_transaction &&
++ (fs_info->running_transaction->state ==
++ TRANS_STATE_COMMIT_START))
++ nolock = true;
++ spin_unlock(&fs_info->trans_lock);
++ }
+
+ if (test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags)) {
+ ret = -EIO;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index acdad6d658f5..42d756267e9a 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -1888,17 +1888,8 @@ static void btrfs_cleanup_pending_block_groups(struct btrfs_trans_handle *trans)
+
+ static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
+ {
+- /*
+- * We use writeback_inodes_sb here because if we used
+- * btrfs_start_delalloc_roots we would deadlock with fs freeze.
+- * Currently are holding the fs freeze lock, if we do an async flush
+- * we'll do btrfs_join_transaction() and deadlock because we need to
+- * wait for the fs freeze lock. Using the direct flushing we benefit
+- * from already being in a transaction and our join_transaction doesn't
+- * have to re-take the fs freeze lock.
+- */
+ if (btrfs_test_opt(fs_info, FLUSHONCOMMIT))
+- writeback_inodes_sb(fs_info->sb, WB_REASON_SYNC);
++ return btrfs_start_delalloc_roots(fs_info, 1, -1);
+ return 0;
+ }
+