@@ -138,6 +138,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid);
138
138
* and once to do all the other items.
139
139
*/
140
140
141
+ static struct inode * btrfs_iget_logging (u64 objectid , struct btrfs_root * root )
142
+ {
143
+ unsigned int nofs_flag ;
144
+ struct inode * inode ;
145
+
146
+ /*
147
+ * We're holding a transaction handle whether we are logging or
148
+ * replaying a log tree, so we must make sure NOFS semantics apply
149
+ * because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL
150
+ * to allocate an inode, which can recurse back into the filesystem and
151
+ * attempt a transaction commit, resulting in a deadlock.
152
+ */
153
+ nofs_flag = memalloc_nofs_save ();
154
+ inode = btrfs_iget (root -> fs_info -> sb , objectid , root );
155
+ memalloc_nofs_restore (nofs_flag );
156
+
157
+ return inode ;
158
+ }
159
+
141
160
/*
142
161
* start a sub transaction and setup the log tree
143
162
* this increments the log tree writer count to make the people
@@ -600,7 +619,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
600
619
{
601
620
struct inode * inode ;
602
621
603
- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
622
+ inode = btrfs_iget_logging ( objectid , root );
604
623
if (IS_ERR (inode ))
605
624
inode = NULL ;
606
625
return inode ;
@@ -5438,7 +5457,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5438
5457
struct btrfs_log_ctx * ctx )
5439
5458
{
5440
5459
struct btrfs_root * root = start_inode -> root ;
5441
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5442
5460
struct btrfs_path * path ;
5443
5461
LIST_HEAD (dir_list );
5444
5462
struct btrfs_dir_list * dir_elem ;
@@ -5499,7 +5517,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5499
5517
continue ;
5500
5518
5501
5519
btrfs_release_path (path );
5502
- di_inode = btrfs_iget ( fs_info -> sb , di_key .objectid , root );
5520
+ di_inode = btrfs_iget_logging ( di_key .objectid , root );
5503
5521
if (IS_ERR (di_inode )) {
5504
5522
ret = PTR_ERR (di_inode );
5505
5523
goto out ;
@@ -5559,7 +5577,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5559
5577
btrfs_add_delayed_iput (curr_inode );
5560
5578
curr_inode = NULL ;
5561
5579
5562
- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5580
+ vfs_inode = btrfs_iget_logging ( ino , root );
5563
5581
if (IS_ERR (vfs_inode )) {
5564
5582
ret = PTR_ERR (vfs_inode );
5565
5583
break ;
@@ -5654,7 +5672,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
5654
5672
if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
5655
5673
return BTRFS_LOG_FORCE_COMMIT ;
5656
5674
5657
- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5675
+ inode = btrfs_iget_logging ( ino , root );
5658
5676
/*
5659
5677
* If the other inode that had a conflicting dir entry was deleted in
5660
5678
* the current transaction then we either:
@@ -5755,7 +5773,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5755
5773
struct btrfs_root * root ,
5756
5774
struct btrfs_log_ctx * ctx )
5757
5775
{
5758
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5759
5776
int ret = 0 ;
5760
5777
5761
5778
/*
@@ -5786,7 +5803,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5786
5803
list_del (& curr -> list );
5787
5804
kfree (curr );
5788
5805
5789
- inode = btrfs_iget ( fs_info -> sb , ino , root );
5806
+ inode = btrfs_iget_logging ( ino , root );
5790
5807
/*
5791
5808
* If the other inode that had a conflicting dir entry was
5792
5809
* deleted in the current transaction, we need to log its parent
@@ -5797,7 +5814,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5797
5814
if (ret != - ENOENT )
5798
5815
break ;
5799
5816
5800
- inode = btrfs_iget ( fs_info -> sb , parent , root );
5817
+ inode = btrfs_iget_logging ( parent , root );
5801
5818
if (IS_ERR (inode )) {
5802
5819
ret = PTR_ERR (inode );
5803
5820
break ;
@@ -6319,7 +6336,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6319
6336
struct btrfs_log_ctx * ctx )
6320
6337
{
6321
6338
const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6322
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6323
6339
struct btrfs_delayed_item * item ;
6324
6340
int ret = 0 ;
6325
6341
@@ -6345,7 +6361,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6345
6361
if (key .type == BTRFS_ROOT_ITEM_KEY )
6346
6362
continue ;
6347
6363
6348
- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6364
+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
6349
6365
if (IS_ERR (di_inode )) {
6350
6366
ret = PTR_ERR (di_inode );
6351
6367
break ;
@@ -6729,7 +6745,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6729
6745
struct btrfs_inode * inode ,
6730
6746
struct btrfs_log_ctx * ctx )
6731
6747
{
6732
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6733
6748
int ret ;
6734
6749
struct btrfs_path * path ;
6735
6750
struct btrfs_key key ;
@@ -6794,8 +6809,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6794
6809
cur_offset = item_size ;
6795
6810
}
6796
6811
6797
- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6798
- root );
6812
+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
6799
6813
/*
6800
6814
* If the parent inode was deleted, return an error to
6801
6815
* fallback to a transaction commit. This is to prevent
@@ -6857,7 +6871,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6857
6871
btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
6858
6872
6859
6873
while (true) {
6860
- struct btrfs_fs_info * fs_info = root -> fs_info ;
6861
6874
struct extent_buffer * leaf ;
6862
6875
int slot ;
6863
6876
struct btrfs_key search_key ;
@@ -6872,7 +6885,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6872
6885
search_key .objectid = found_key .offset ;
6873
6886
search_key .type = BTRFS_INODE_ITEM_KEY ;
6874
6887
search_key .offset = 0 ;
6875
- inode = btrfs_iget ( fs_info -> sb , ino , root );
6888
+ inode = btrfs_iget_logging ( ino , root );
6876
6889
if (IS_ERR (inode ))
6877
6890
return PTR_ERR (inode );
6878
6891
0 commit comments