diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 24 | 
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5c5bc5dafff..2c8caa51add 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -193,7 +193,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)   * so before we call here everything must be consistently dirtied against   * this transaction.   */ - int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode, +int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,  				 int nblocks)  {  	int ret; @@ -209,6 +209,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)  	up_write(&EXT4_I(inode)->i_data_sem);  	ret = ext4_journal_restart(handle, blocks_for_truncate(inode));  	down_write(&EXT4_I(inode)->i_data_sem); +	ext4_discard_preallocations(inode);  	return ret;  } @@ -3445,8 +3446,6 @@ out:  	return ret;  } -/* Maximum number of blocks we map for direct IO at once. */ -  static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,  		   struct buffer_head *bh_result, int create)  { @@ -3654,13 +3653,14 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,          ext4_io_end_t *io_end = iocb->private;  	struct workqueue_struct *wq; +	/* if not async direct IO or dio with 0 bytes write, just return */ +	if (!io_end || !size) +		return; +  	ext_debug("ext4_end_io_dio(): io_end 0x%p"  		  "for inode %lu, iocb 0x%p, offset %llu, size %llu\n",   		  iocb->private, io_end->inode->i_ino, iocb, offset,  		  size); -	/* if not async direct IO or dio with 0 bytes write, just return */ -	if (!io_end || !size) -		return;  	/* if not aio dio with unwritten extents, just free io and return */  	if (io_end->flag != DIO_AIO_UNWRITTEN){ @@ -3771,13 +3771,19 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,  		if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {  			ext4_free_io_end(iocb->private);  			iocb->private = NULL; -		} else if (ret > 0) +		} else if (ret > 0 && (EXT4_I(inode)->i_state & +				       EXT4_STATE_DIO_UNWRITTEN)) { +			int err;  			/*  			 * for non AIO case, since the IO is already  			 * completed, we could do the convertion right here  			 */ -			ret = ext4_convert_unwritten_extents(inode, -								offset, ret); +			err = ext4_convert_unwritten_extents(inode, +							     offset, ret); +			if (err < 0) +				ret = err; +			EXT4_I(inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN; +		}  		return ret;  	}  |