@@ -140,6 +140,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid);
140
140
* and once to do all the other items.
141
141
*/
142
142
143
+ static struct inode * btrfs_iget_logging (u64 objectid , struct btrfs_root * root )
144
+ {
145
+ unsigned int nofs_flag ;
146
+ struct inode * inode ;
147
+
148
+ /*
149
+ * We're holding a transaction handle whether we are logging or
150
+ * replaying a log tree, so we must make sure NOFS semantics apply
151
+ * because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL
152
+ * to allocate an inode, which can recurse back into the filesystem and
153
+ * attempt a transaction commit, resulting in a deadlock.
154
+ */
155
+ nofs_flag = memalloc_nofs_save ();
156
+ inode = btrfs_iget (root -> fs_info -> sb , objectid , root );
157
+ memalloc_nofs_restore (nofs_flag );
158
+
159
+ return inode ;
160
+ }
161
+
143
162
/*
144
163
* start a sub transaction and setup the log tree
145
164
* this increments the log tree writer count to make the people
@@ -603,7 +622,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
603
622
{
604
623
struct inode * inode ;
605
624
606
- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
625
+ inode = btrfs_iget_logging ( objectid , root );
607
626
if (IS_ERR (inode ))
608
627
inode = NULL ;
609
628
return inode ;
@@ -5377,7 +5396,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5377
5396
struct btrfs_log_ctx * ctx )
5378
5397
{
5379
5398
struct btrfs_root * root = start_inode -> root ;
5380
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5381
5399
struct btrfs_path * path ;
5382
5400
LIST_HEAD (dir_list );
5383
5401
struct btrfs_dir_list * dir_elem ;
@@ -5438,7 +5456,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5438
5456
continue ;
5439
5457
5440
5458
btrfs_release_path (path );
5441
- di_inode = btrfs_iget ( fs_info -> sb , di_key .objectid , root );
5459
+ di_inode = btrfs_iget_logging ( di_key .objectid , root );
5442
5460
if (IS_ERR (di_inode )) {
5443
5461
ret = PTR_ERR (di_inode );
5444
5462
goto out ;
@@ -5498,7 +5516,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5498
5516
btrfs_add_delayed_iput (curr_inode );
5499
5517
curr_inode = NULL ;
5500
5518
5501
- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5519
+ vfs_inode = btrfs_iget_logging ( ino , root );
5502
5520
if (IS_ERR (vfs_inode )) {
5503
5521
ret = PTR_ERR (vfs_inode );
5504
5522
break ;
@@ -5593,7 +5611,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
5593
5611
if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
5594
5612
return BTRFS_LOG_FORCE_COMMIT ;
5595
5613
5596
- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5614
+ inode = btrfs_iget_logging ( ino , root );
5597
5615
/*
5598
5616
* If the other inode that had a conflicting dir entry was deleted in
5599
5617
* the current transaction then we either:
@@ -5694,7 +5712,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5694
5712
struct btrfs_root * root ,
5695
5713
struct btrfs_log_ctx * ctx )
5696
5714
{
5697
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5698
5715
int ret = 0 ;
5699
5716
5700
5717
/*
@@ -5725,7 +5742,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5725
5742
list_del (& curr -> list );
5726
5743
kfree (curr );
5727
5744
5728
- inode = btrfs_iget ( fs_info -> sb , ino , root );
5745
+ inode = btrfs_iget_logging ( ino , root );
5729
5746
/*
5730
5747
* If the other inode that had a conflicting dir entry was
5731
5748
* deleted in the current transaction, we need to log its parent
@@ -5736,7 +5753,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5736
5753
if (ret != - ENOENT )
5737
5754
break ;
5738
5755
5739
- inode = btrfs_iget ( fs_info -> sb , parent , root );
5756
+ inode = btrfs_iget_logging ( parent , root );
5740
5757
if (IS_ERR (inode )) {
5741
5758
ret = PTR_ERR (inode );
5742
5759
break ;
@@ -6258,7 +6275,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6258
6275
struct btrfs_log_ctx * ctx )
6259
6276
{
6260
6277
const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6261
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6262
6278
struct btrfs_delayed_item * item ;
6263
6279
int ret = 0 ;
6264
6280
@@ -6284,7 +6300,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6284
6300
if (key .type == BTRFS_ROOT_ITEM_KEY )
6285
6301
continue ;
6286
6302
6287
- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6303
+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
6288
6304
if (IS_ERR (di_inode )) {
6289
6305
ret = PTR_ERR (di_inode );
6290
6306
break ;
@@ -6668,7 +6684,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6668
6684
struct btrfs_inode * inode ,
6669
6685
struct btrfs_log_ctx * ctx )
6670
6686
{
6671
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6672
6687
int ret ;
6673
6688
struct btrfs_path * path ;
6674
6689
struct btrfs_key key ;
@@ -6733,8 +6748,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6733
6748
cur_offset = item_size ;
6734
6749
}
6735
6750
6736
- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6737
- root );
6751
+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
6738
6752
/*
6739
6753
* If the parent inode was deleted, return an error to
6740
6754
* fallback to a transaction commit. This is to prevent
@@ -6796,7 +6810,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6796
6810
btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
6797
6811
6798
6812
while (true) {
6799
- struct btrfs_fs_info * fs_info = root -> fs_info ;
6800
6813
struct extent_buffer * leaf ;
6801
6814
int slot ;
6802
6815
struct btrfs_key search_key ;
@@ -6811,7 +6824,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6811
6824
search_key .objectid = found_key .offset ;
6812
6825
search_key .type = BTRFS_INODE_ITEM_KEY ;
6813
6826
search_key .offset = 0 ;
6814
- inode = btrfs_iget ( fs_info -> sb , ino , root );
6827
+ inode = btrfs_iget_logging ( ino , root );
6815
6828
if (IS_ERR (inode ))
6816
6829
return PTR_ERR (inode );
6817
6830
0 commit comments