diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 48 | 
1 files changed, 28 insertions, 20 deletions
| diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 78701445348f..760c5f40a555 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1545,6 +1545,8 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,  			BUG_ON(!PageLocked(page));  			BUG_ON(PageWriteback(page));  			if (invalidate) { +				if (page_mapped(page)) +					clear_page_dirty_for_io(page);  				block_invalidatepage(page, 0, PAGE_CACHE_SIZE);  				ClearPageUptodate(page);  			} @@ -3297,29 +3299,29 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter,  	 * case, we allocate an io_end structure to hook to the iocb.  	 */  	iocb->private = NULL; -	ext4_inode_aio_set(inode, NULL); -	if (!is_sync_kiocb(iocb)) { -		io_end = ext4_init_io_end(inode, GFP_NOFS); -		if (!io_end) { -			ret = -ENOMEM; -			goto retake_lock; -		} -		/* -		 * Grab reference for DIO. Will be dropped in ext4_end_io_dio() -		 */ -		iocb->private = ext4_get_io_end(io_end); -		/* -		 * we save the io structure for current async direct -		 * IO, so that later ext4_map_blocks() could flag the -		 * io structure whether there is a unwritten extents -		 * needs to be converted when IO is completed. -		 */ -		ext4_inode_aio_set(inode, io_end); -	} -  	if (overwrite) {  		get_block_func = ext4_get_block_write_nolock;  	} else { +		ext4_inode_aio_set(inode, NULL); +		if (!is_sync_kiocb(iocb)) { +			io_end = ext4_init_io_end(inode, GFP_NOFS); +			if (!io_end) { +				ret = -ENOMEM; +				goto retake_lock; +			} +			/* +			 * Grab reference for DIO. Will be dropped in +			 * ext4_end_io_dio() +			 */ +			iocb->private = ext4_get_io_end(io_end); +			/* +			 * we save the io structure for current async direct +			 * IO, so that later ext4_map_blocks() could flag the +			 * io structure whether there is a unwritten extents +			 * needs to be converted when IO is completed. +			 */ +			ext4_inode_aio_set(inode, io_end); +		}  		get_block_func = ext4_get_block_write;  		dio_flags = DIO_LOCKING;  	} @@ -4317,6 +4319,12 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)  		goto bad_inode;  	raw_inode = ext4_raw_inode(&iloc); +	if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { +		EXT4_ERROR_INODE(inode, "root inode unallocated"); +		ret = -EFSCORRUPTED; +		goto bad_inode; +	} +  	if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {  		ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);  		if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > | 
