@@ -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
@@ -603,7 +622,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root,
603622{
604623 struct inode * inode ;
605624
606- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
625+ inode = btrfs_iget_logging ( objectid , root );
607626 if (IS_ERR (inode ))
608627 inode = NULL ;
609628 return inode ;
@@ -5377,7 +5396,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
53775396 struct btrfs_log_ctx * ctx )
53785397{
53795398 struct btrfs_root * root = start_inode -> root ;
5380- struct btrfs_fs_info * fs_info = root -> fs_info ;
53815399 struct btrfs_path * path ;
53825400 LIST_HEAD (dir_list );
53835401 struct btrfs_dir_list * dir_elem ;
@@ -5438,7 +5456,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54385456 continue ;
54395457
54405458 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 );
54425460 if (IS_ERR (di_inode )) {
54435461 ret = PTR_ERR (di_inode );
54445462 goto out ;
@@ -5498,7 +5516,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54985516 btrfs_add_delayed_iput (curr_inode );
54995517 curr_inode = NULL ;
55005518
5501- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5519+ vfs_inode = btrfs_iget_logging ( ino , root );
55025520 if (IS_ERR (vfs_inode )) {
55035521 ret = PTR_ERR (vfs_inode );
55045522 break ;
@@ -5593,7 +5611,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
55935611 if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
55945612 return BTRFS_LOG_FORCE_COMMIT ;
55955613
5596- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5614+ inode = btrfs_iget_logging ( ino , root );
55975615 /*
55985616 * If the other inode that had a conflicting dir entry was deleted in
55995617 * the current transaction then we either:
@@ -5694,7 +5712,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
56945712 struct btrfs_root * root ,
56955713 struct btrfs_log_ctx * ctx )
56965714{
5697- struct btrfs_fs_info * fs_info = root -> fs_info ;
56985715 int ret = 0 ;
56995716
57005717 /*
@@ -5725,7 +5742,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
57255742 list_del (& curr -> list );
57265743 kfree (curr );
57275744
5728- inode = btrfs_iget ( fs_info -> sb , ino , root );
5745+ inode = btrfs_iget_logging ( ino , root );
57295746 /*
57305747 * If the other inode that had a conflicting dir entry was
57315748 * 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,
57365753 if (ret != - ENOENT )
57375754 break ;
57385755
5739- inode = btrfs_iget ( fs_info -> sb , parent , root );
5756+ inode = btrfs_iget_logging ( parent , root );
57405757 if (IS_ERR (inode )) {
57415758 ret = PTR_ERR (inode );
57425759 break ;
@@ -6258,7 +6275,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
62586275 struct btrfs_log_ctx * ctx )
62596276{
62606277 const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6261- struct btrfs_fs_info * fs_info = trans -> fs_info ;
62626278 struct btrfs_delayed_item * item ;
62636279 int ret = 0 ;
62646280
@@ -6284,7 +6300,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
62846300 if (key .type == BTRFS_ROOT_ITEM_KEY )
62856301 continue ;
62866302
6287- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6303+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
62886304 if (IS_ERR (di_inode )) {
62896305 ret = PTR_ERR (di_inode );
62906306 break ;
@@ -6668,7 +6684,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
66686684 struct btrfs_inode * inode ,
66696685 struct btrfs_log_ctx * ctx )
66706686{
6671- struct btrfs_fs_info * fs_info = trans -> fs_info ;
66726687 int ret ;
66736688 struct btrfs_path * path ;
66746689 struct btrfs_key key ;
@@ -6733,8 +6748,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
67336748 cur_offset = item_size ;
67346749 }
67356750
6736- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6737- root );
6751+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
67386752 /*
67396753 * If the parent inode was deleted, return an error to
67406754 * fallback to a transaction commit. This is to prevent
@@ -6796,7 +6810,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
67966810 btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
67976811
67986812 while (true) {
6799- struct btrfs_fs_info * fs_info = root -> fs_info ;
68006813 struct extent_buffer * leaf ;
68016814 int slot ;
68026815 struct btrfs_key search_key ;
@@ -6811,7 +6824,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
68116824 search_key .objectid = found_key .offset ;
68126825 search_key .type = BTRFS_INODE_ITEM_KEY ;
68136826 search_key .offset = 0 ;
6814- inode = btrfs_iget ( fs_info -> sb , ino , root );
6827+ inode = btrfs_iget_logging ( ino , root );
68156828 if (IS_ERR (inode ))
68166829 return PTR_ERR (inode );
68176830
0 commit comments