@@ -140,6 +140,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid);
140140 * and once to do all the other items.
141141 */
142142
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+
143162/*
144163 * start a sub transaction and setup the log tree
145164 * 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,
602621{
603622 struct inode * inode ;
604623
605- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
624+ inode = btrfs_iget_logging ( objectid , root );
606625 if (IS_ERR (inode ))
607626 inode = NULL ;
608627 return inode ;
@@ -5371,7 +5390,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
53715390 struct btrfs_log_ctx * ctx )
53725391{
53735392 struct btrfs_root * root = start_inode -> root ;
5374- struct btrfs_fs_info * fs_info = root -> fs_info ;
53755393 struct btrfs_path * path ;
53765394 LIST_HEAD (dir_list );
53775395 struct btrfs_dir_list * dir_elem ;
@@ -5432,7 +5450,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54325450 continue ;
54335451
54345452 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 );
54365454 if (IS_ERR (di_inode )) {
54375455 ret = PTR_ERR (di_inode );
54385456 goto out ;
@@ -5492,7 +5510,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54925510 btrfs_add_delayed_iput (curr_inode );
54935511 curr_inode = NULL ;
54945512
5495- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5513+ vfs_inode = btrfs_iget_logging ( ino , root );
54965514 if (IS_ERR (vfs_inode )) {
54975515 ret = PTR_ERR (vfs_inode );
54985516 break ;
@@ -5587,7 +5605,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
55875605 if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
55885606 return BTRFS_LOG_FORCE_COMMIT ;
55895607
5590- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5608+ inode = btrfs_iget_logging ( ino , root );
55915609 /*
55925610 * If the other inode that had a conflicting dir entry was deleted in
55935611 * the current transaction then we either:
@@ -5688,7 +5706,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
56885706 struct btrfs_root * root ,
56895707 struct btrfs_log_ctx * ctx )
56905708{
5691- struct btrfs_fs_info * fs_info = root -> fs_info ;
56925709 int ret = 0 ;
56935710
56945711 /*
@@ -5719,7 +5736,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
57195736 list_del (& curr -> list );
57205737 kfree (curr );
57215738
5722- inode = btrfs_iget ( fs_info -> sb , ino , root );
5739+ inode = btrfs_iget_logging ( ino , root );
57235740 /*
57245741 * If the other inode that had a conflicting dir entry was
57255742 * 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,
57305747 if (ret != - ENOENT )
57315748 break ;
57325749
5733- inode = btrfs_iget ( fs_info -> sb , parent , root );
5750+ inode = btrfs_iget_logging ( parent , root );
57345751 if (IS_ERR (inode )) {
57355752 ret = PTR_ERR (inode );
57365753 break ;
@@ -6252,7 +6269,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
62526269 struct btrfs_log_ctx * ctx )
62536270{
62546271 const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6255- struct btrfs_fs_info * fs_info = trans -> fs_info ;
62566272 struct btrfs_delayed_item * item ;
62576273 int ret = 0 ;
62586274
@@ -6278,7 +6294,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
62786294 if (key .type == BTRFS_ROOT_ITEM_KEY )
62796295 continue ;
62806296
6281- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6297+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
62826298 if (IS_ERR (di_inode )) {
62836299 ret = PTR_ERR (di_inode );
62846300 break ;
@@ -6662,7 +6678,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
66626678 struct btrfs_inode * inode ,
66636679 struct btrfs_log_ctx * ctx )
66646680{
6665- struct btrfs_fs_info * fs_info = trans -> fs_info ;
66666681 int ret ;
66676682 struct btrfs_path * path ;
66686683 struct btrfs_key key ;
@@ -6727,8 +6742,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
67276742 cur_offset = item_size ;
67286743 }
67296744
6730- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6731- root );
6745+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
67326746 /*
67336747 * If the parent inode was deleted, return an error to
67346748 * fallback to a transaction commit. This is to prevent
@@ -6790,7 +6804,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
67906804 btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
67916805
67926806 while (true) {
6793- struct btrfs_fs_info * fs_info = root -> fs_info ;
67946807 struct extent_buffer * leaf ;
67956808 int slot ;
67966809 struct btrfs_key search_key ;
@@ -6805,7 +6818,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
68056818 search_key .objectid = found_key .offset ;
68066819 search_key .type = BTRFS_INODE_ITEM_KEY ;
68076820 search_key .offset = 0 ;
6808- inode = btrfs_iget ( fs_info -> sb , ino , root );
6821+ inode = btrfs_iget_logging ( ino , root );
68096822 if (IS_ERR (inode ))
68106823 return PTR_ERR (inode );
68116824
0 commit comments