mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 00:28:52 +02:00 
			
		
		
		
	udf: Protect truncate and file type conversion with invalidate_lock
Protect truncate and file type conversion in udf_file_write_iter() with invalidate lock. That will allow us to serialize these paths with page faults so that the page fault can determine the file type in a racefree way. Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
		
							parent
							
								
									96eeaaaea5
								
							
						
					
					
						commit
						b9a861fd52
					
				
					 2 changed files with 11 additions and 6 deletions
				
			
		|  | @ -150,7 +150,9 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
| 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && | ||||
| 	    inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + | ||||
| 				 iocb->ki_pos + iov_iter_count(from))) { | ||||
| 		filemap_invalidate_lock(inode->i_mapping); | ||||
| 		retval = udf_expand_file_adinicb(inode); | ||||
| 		filemap_invalidate_unlock(inode->i_mapping); | ||||
| 		if (retval) | ||||
| 			goto out; | ||||
| 	} | ||||
|  |  | |||
|  | @ -1145,7 +1145,7 @@ struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, | |||
| 
 | ||||
| int udf_setsize(struct inode *inode, loff_t newsize) | ||||
| { | ||||
| 	int err; | ||||
| 	int err = 0; | ||||
| 	struct udf_inode_info *iinfo; | ||||
| 	unsigned int bsize = i_blocksize(inode); | ||||
| 
 | ||||
|  | @ -1155,6 +1155,7 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
| 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||||
| 		return -EPERM; | ||||
| 
 | ||||
| 	filemap_invalidate_lock(inode->i_mapping); | ||||
| 	iinfo = UDF_I(inode); | ||||
| 	if (newsize > inode->i_size) { | ||||
| 		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | ||||
|  | @ -1167,11 +1168,11 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
| 			} | ||||
| 			err = udf_expand_file_adinicb(inode); | ||||
| 			if (err) | ||||
| 				return err; | ||||
| 				goto out_unlock; | ||||
| 		} | ||||
| 		err = udf_extend_file(inode, newsize); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 			goto out_unlock; | ||||
| set_size: | ||||
| 		truncate_setsize(inode, newsize); | ||||
| 	} else { | ||||
|  | @ -1189,14 +1190,14 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
| 		err = block_truncate_page(inode->i_mapping, newsize, | ||||
| 					  udf_get_block); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 			goto out_unlock; | ||||
| 		truncate_setsize(inode, newsize); | ||||
| 		down_write(&iinfo->i_data_sem); | ||||
| 		udf_clear_extent_cache(inode); | ||||
| 		err = udf_truncate_extents(inode); | ||||
| 		up_write(&iinfo->i_data_sem); | ||||
| 		if (err) | ||||
| 			return err; | ||||
| 			goto out_unlock; | ||||
| 	} | ||||
| update_time: | ||||
| 	inode->i_mtime = inode->i_ctime = current_time(inode); | ||||
|  | @ -1204,7 +1205,9 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
| 		udf_sync_inode(inode); | ||||
| 	else | ||||
| 		mark_inode_dirty(inode); | ||||
| 	return 0; | ||||
| out_unlock: | ||||
| 	filemap_invalidate_unlock(inode->i_mapping); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jan Kara
						Jan Kara