@@ -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