@@ -138,6 +138,25 @@ static void wait_log_commit(struct btrfs_root *root, int transid);
138138 * and once to do all the other items.
139139 */
140140
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+
141160/*
142161 * start a sub transaction and setup the log tree
143162 * 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,
600619{
601620 struct inode * inode ;
602621
603- inode = btrfs_iget ( root -> fs_info -> sb , objectid , root );
622+ inode = btrfs_iget_logging ( objectid , root );
604623 if (IS_ERR (inode ))
605624 inode = NULL ;
606625 return inode ;
@@ -5438,7 +5457,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54385457 struct btrfs_log_ctx * ctx )
54395458{
54405459 struct btrfs_root * root = start_inode -> root ;
5441- struct btrfs_fs_info * fs_info = root -> fs_info ;
54425460 struct btrfs_path * path ;
54435461 LIST_HEAD (dir_list );
54445462 struct btrfs_dir_list * dir_elem ;
@@ -5499,7 +5517,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
54995517 continue ;
55005518
55015519 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 );
55035521 if (IS_ERR (di_inode )) {
55045522 ret = PTR_ERR (di_inode );
55055523 goto out ;
@@ -5559,7 +5577,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
55595577 btrfs_add_delayed_iput (curr_inode );
55605578 curr_inode = NULL ;
55615579
5562- vfs_inode = btrfs_iget ( fs_info -> sb , ino , root );
5580+ vfs_inode = btrfs_iget_logging ( ino , root );
55635581 if (IS_ERR (vfs_inode )) {
55645582 ret = PTR_ERR (vfs_inode );
55655583 break ;
@@ -5654,7 +5672,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans,
56545672 if (ctx -> num_conflict_inodes >= MAX_CONFLICT_INODES )
56555673 return BTRFS_LOG_FORCE_COMMIT ;
56565674
5657- inode = btrfs_iget ( root -> fs_info -> sb , ino , root );
5675+ inode = btrfs_iget_logging ( ino , root );
56585676 /*
56595677 * If the other inode that had a conflicting dir entry was deleted in
56605678 * the current transaction then we either:
@@ -5755,7 +5773,6 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
57555773 struct btrfs_root * root ,
57565774 struct btrfs_log_ctx * ctx )
57575775{
5758- struct btrfs_fs_info * fs_info = root -> fs_info ;
57595776 int ret = 0 ;
57605777
57615778 /*
@@ -5786,7 +5803,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
57865803 list_del (& curr -> list );
57875804 kfree (curr );
57885805
5789- inode = btrfs_iget ( fs_info -> sb , ino , root );
5806+ inode = btrfs_iget_logging ( ino , root );
57905807 /*
57915808 * If the other inode that had a conflicting dir entry was
57925809 * 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,
57975814 if (ret != - ENOENT )
57985815 break ;
57995816
5800- inode = btrfs_iget ( fs_info -> sb , parent , root );
5817+ inode = btrfs_iget_logging ( parent , root );
58015818 if (IS_ERR (inode )) {
58025819 ret = PTR_ERR (inode );
58035820 break ;
@@ -6319,7 +6336,6 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
63196336 struct btrfs_log_ctx * ctx )
63206337{
63216338 const bool orig_log_new_dentries = ctx -> log_new_dentries ;
6322- struct btrfs_fs_info * fs_info = trans -> fs_info ;
63236339 struct btrfs_delayed_item * item ;
63246340 int ret = 0 ;
63256341
@@ -6345,7 +6361,7 @@ static int log_new_delayed_dentries(struct btrfs_trans_handle *trans,
63456361 if (key .type == BTRFS_ROOT_ITEM_KEY )
63466362 continue ;
63476363
6348- di_inode = btrfs_iget ( fs_info -> sb , key .objectid , inode -> root );
6364+ di_inode = btrfs_iget_logging ( key .objectid , inode -> root );
63496365 if (IS_ERR (di_inode )) {
63506366 ret = PTR_ERR (di_inode );
63516367 break ;
@@ -6729,7 +6745,6 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
67296745 struct btrfs_inode * inode ,
67306746 struct btrfs_log_ctx * ctx )
67316747{
6732- struct btrfs_fs_info * fs_info = trans -> fs_info ;
67336748 int ret ;
67346749 struct btrfs_path * path ;
67356750 struct btrfs_key key ;
@@ -6794,8 +6809,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
67946809 cur_offset = item_size ;
67956810 }
67966811
6797- dir_inode = btrfs_iget (fs_info -> sb , inode_key .objectid ,
6798- root );
6812+ dir_inode = btrfs_iget_logging (inode_key .objectid , root );
67996813 /*
68006814 * If the parent inode was deleted, return an error to
68016815 * fallback to a transaction commit. This is to prevent
@@ -6857,7 +6871,6 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
68576871 btrfs_item_key_to_cpu (path -> nodes [0 ], & found_key , path -> slots [0 ]);
68586872
68596873 while (true) {
6860- struct btrfs_fs_info * fs_info = root -> fs_info ;
68616874 struct extent_buffer * leaf ;
68626875 int slot ;
68636876 struct btrfs_key search_key ;
@@ -6872,7 +6885,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
68726885 search_key .objectid = found_key .offset ;
68736886 search_key .type = BTRFS_INODE_ITEM_KEY ;
68746887 search_key .offset = 0 ;
6875- inode = btrfs_iget ( fs_info -> sb , ino , root );
6888+ inode = btrfs_iget_logging ( ino , root );
68766889 if (IS_ERR (inode ))
68776890 return PTR_ERR (inode );
68786891
0 commit comments