diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 20 | 
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d0dd585add6a..d767e993591d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3413,12 +3413,16 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,  {  	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);  	unsigned int blkbits = inode->i_blkbits; -	unsigned long first_block = offset >> blkbits; -	unsigned long last_block = (offset + length - 1) >> blkbits; +	unsigned long first_block, last_block;  	struct ext4_map_blocks map;  	bool delalloc = false;  	int ret; +	if ((offset >> blkbits) > EXT4_MAX_LOGICAL_BLOCK) +		return -EINVAL; +	first_block = offset >> blkbits; +	last_block = min_t(loff_t, (offset + length - 1) >> blkbits, +			   EXT4_MAX_LOGICAL_BLOCK);  	if (flags & IOMAP_REPORT) {  		if (ext4_has_inline_data(inode)) { @@ -3948,6 +3952,7 @@ static const struct address_space_operations ext4_dax_aops = {  	.writepages		= ext4_dax_writepages,  	.direct_IO		= noop_direct_IO,  	.set_page_dirty		= noop_set_page_dirty, +	.bmap			= ext4_bmap,  	.invalidatepage		= noop_invalidatepage,  }; @@ -4192,9 +4197,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,  	return 0;  } -static void ext4_wait_dax_page(struct ext4_inode_info *ei, bool *did_unlock) +static void ext4_wait_dax_page(struct ext4_inode_info *ei)  { -	*did_unlock = true;  	up_write(&ei->i_mmap_sem);  	schedule();  	down_write(&ei->i_mmap_sem); @@ -4204,14 +4208,12 @@ int ext4_break_layouts(struct inode *inode)  {  	struct ext4_inode_info *ei = EXT4_I(inode);  	struct page *page; -	bool retry;  	int error;  	if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))  		return -EINVAL;  	do { -		retry = false;  		page = dax_layout_busy_page(inode->i_mapping);  		if (!page)  			return 0; @@ -4219,8 +4221,8 @@ int ext4_break_layouts(struct inode *inode)  		error = ___wait_var_event(&page->_refcount,  				atomic_read(&page->_refcount) == 1,  				TASK_INTERRUPTIBLE, 0, 0, -				ext4_wait_dax_page(ei, &retry)); -	} while (error == 0 && retry); +				ext4_wait_dax_page(ei)); +	} while (error == 0);  	return error;  } @@ -4895,6 +4897,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)  		 * not initialized on a new filesystem. */  	}  	ei->i_flags = le32_to_cpu(raw_inode->i_flags); +	ext4_set_inode_flags(inode);  	inode->i_blocks = ext4_inode_blocks(raw_inode, ei);  	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);  	if (ext4_has_feature_64bit(sb)) @@ -5041,7 +5044,6 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)  		goto bad_inode;  	}  	brelse(iloc.bh); -	ext4_set_inode_flags(inode);  	unlock_new_inode(inode);  	return inode;  |