@@ -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
@@ -602,7 +621,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
602
621
{
603
622
struct inode * inode ;
604
623
605
- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
624
+ inode = btrfs_iget_logging ( objectid , root );
606
625
if (IS_ERR (inode ))
607
626
inode = NULL ;
608
627
return inode ;
@@ -5371,7 +5390,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5371
5390
struct btrfs_log_ctx * ctx )
5372
5391
{
5373
5392
struct btrfs_root * root = start_inode -> root ;
5374
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5375
5393
struct btrfs_path * path ;
5376
5394
LIST_HEAD (dir_list );
5377
5395
struct btrfs_dir_list * dir_elem ;
@@ -5432,7 +5450,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5432
5450
continue ;
5433
5451
5434
5452
btrfs_release_path (path );
5435
- di_inode = btrfs_iget ( fs_info -> sb , di_key .objectid , root );
5453
+ di_inode = btrfs_iget_logging ( di_key .objectid , root );
5436
5454
if (IS_ERR (di_inode )) {
5437
5455
ret = PTR_ERR (di_inode );
5438
5456
goto out ;
@@ -5492,7 +5510,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
5492
5510
btrfs_add_delayed_iput (curr_inode );
5493
5511
curr_inode = NULL ;
5494
5512
5495
- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5513
+ vfs_inode = btrfs_iget_logging ( ino , root );
5496
5514
if (IS_ERR (vfs_inode )) {
5497
5515
ret = PTR_ERR (vfs_inode );
5498
5516
break ;
@@ -5587,7 +5605,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
5587
5605
if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
5588
5606
return BTRFS_LOG_FORCE_COMMIT ;
5589
5607
5590
- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5608
+ inode = btrfs_iget_logging ( ino , root );
5591
5609
/*
5592
5610
* If the other inode that had a conflicting dir entry was deleted in
5593
5611
* the current transaction then we either:
@@ -5688,7 +5706,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5688
5706
struct btrfs_root * root ,
5689
5707
struct btrfs_log_ctx * ctx )
5690
5708
{
5691
- struct btrfs_fs_info * fs_info = root -> fs_info ;
5692
5709
int ret = 0 ;
5693
5710
5694
5711
/*
@@ -5719,7 +5736,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5719
5736
list_del (& curr -> list );
5720
5737
kfree (curr );
5721
5738
5722
- inode = btrfs_iget ( fs_info -> sb , ino , root );
5739
+ inode = btrfs_iget_logging ( ino , root );
5723
5740
/*
5724
5741
* If the other inode that had a conflicting dir entry was
5725
5742
* deleted in the current transaction, we need to log its parent
@@ -5730,7 +5747,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
5730
5747
if (ret != - ENOENT )
5731
5748
break ;
5732
5749
5733
- inode = btrfs_iget ( fs_info -> sb , parent , root );
5750
+ inode = btrfs_iget_logging ( parent , root );
5734
5751
if (IS_ERR (inode )) {
5735
5752
ret = PTR_ERR (inode );
5736
5753
break ;
@@ -6252,7 +6269,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6252
6269
struct btrfs_log_ctx * ctx )
6253
6270
{
6254
6271
const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6255
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6256
6272
struct btrfs_delayed_item * item ;
6257
6273
int ret = 0 ;
6258
6274
@@ -6278,7 +6294,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
6278
6294
if (key .type == BTRFS_ROOT_ITEM_KEY )
6279
6295
continue ;
6280
6296
6281
- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6297
+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
6282
6298
if (IS_ERR (di_inode )) {
6283
6299
ret = PTR_ERR (di_inode );
6284
6300
break ;
@@ -6662,7 +6678,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6662
6678
struct btrfs_inode * inode ,
6663
6679
struct btrfs_log_ctx * ctx )
6664
6680
{
6665
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
6666
6681
int ret ;
6667
6682
struct btrfs_path * path ;
6668
6683
struct btrfs_key key ;
@@ -6727,8 +6742,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
6727
6742
cur_offset = item_size ;
6728
6743
}
6729
6744
6730
- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6731
- root );
6745
+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
6732
6746
/*
6733
6747
* If the parent inode was deleted, return an error to
6734
6748
* fallback to a transaction commit. This is to prevent
@@ -6790,7 +6804,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6790
6804
btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
6791
6805
6792
6806
while (true) {
6793
- struct btrfs_fs_info * fs_info = root -> fs_info ;
6794
6807
struct extent_buffer * leaf ;
6795
6808
int slot ;
6796
6809
struct btrfs_key search_key ;
@@ -6805,7 +6818,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
6805
6818
search_key .objectid = found_key .offset ;
6806
6819
search_key .type = BTRFS_INODE_ITEM_KEY ;
6807
6820
search_key .offset = 0 ;
6808
- inode = btrfs_iget ( fs_info -> sb , ino , root );
6821
+ inode = btrfs_iget_logging ( ino , root );
6809
6822
if (IS_ERR (inode ))
6810
6823
return PTR_ERR (inode );
6811
6824
0 commit comments