diff options
Diffstat (limited to 'fs/xfs/xfs_file.c')
| -rw-r--r-- | fs/xfs/xfs_file.c | 42 | 
1 files changed, 23 insertions, 19 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index aa473fa640a..67284edb84d 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -31,6 +31,8 @@  #include "xfs_error.h"  #include "xfs_vnodeops.h"  #include "xfs_da_btree.h" +#include "xfs_dir2_format.h" +#include "xfs_dir2_priv.h"  #include "xfs_ioctl.h"  #include "xfs_trace.h" @@ -84,7 +86,7 @@ xfs_rw_ilock_demote(   *	valid before the operation, it will be read from disk before   *	being partially zeroed.   */ -STATIC int +int  xfs_iozero(  	struct xfs_inode	*ip,	/* inode			*/  	loff_t			pos,	/* offset in file		*/ @@ -255,15 +257,14 @@ xfs_file_aio_read(  		xfs_buftarg_t	*target =  			XFS_IS_REALTIME_INODE(ip) ?  				mp->m_rtdev_targp : mp->m_ddev_targp; -		if ((iocb->ki_pos & target->bt_smask) || -		    (size & target->bt_smask)) { -			if (iocb->ki_pos == i_size_read(inode)) +		if ((pos & target->bt_smask) || (size & target->bt_smask)) { +			if (pos == i_size_read(inode))  				return 0;  			return -XFS_ERROR(EINVAL);  		}  	} -	n = mp->m_super->s_maxbytes - iocb->ki_pos; +	n = mp->m_super->s_maxbytes - pos;  	if (n <= 0 || size == 0)  		return 0; @@ -289,20 +290,21 @@ xfs_file_aio_read(  		xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);  		if (inode->i_mapping->nrpages) { -			ret = -xfs_flushinval_pages(ip, -					(iocb->ki_pos & PAGE_CACHE_MASK), -					-1, FI_REMAPF_LOCKED); +			ret = -filemap_write_and_wait_range( +							VFS_I(ip)->i_mapping, +							pos, -1);  			if (ret) {  				xfs_rw_iunlock(ip, XFS_IOLOCK_EXCL);  				return ret;  			} +			truncate_pagecache_range(VFS_I(ip), pos, -1);  		}  		xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);  	} -	trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags); +	trace_xfs_file_read(ip, size, pos, ioflags); -	ret = generic_file_aio_read(iocb, iovp, nr_segs, iocb->ki_pos); +	ret = generic_file_aio_read(iocb, iovp, nr_segs, pos);  	if (ret > 0)  		XFS_STATS_ADD(xs_read_bytes, ret); @@ -670,10 +672,11 @@ xfs_file_dio_aio_write(  		goto out;  	if (mapping->nrpages) { -		ret = -xfs_flushinval_pages(ip, (pos & PAGE_CACHE_MASK), -1, -							FI_REMAPF_LOCKED); +		ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, +						    pos, -1);  		if (ret)  			goto out; +		truncate_pagecache_range(VFS_I(ip), pos, -1);  	}  	/* @@ -728,16 +731,17 @@ xfs_file_buffered_aio_write(  write_retry:  	trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);  	ret = generic_file_buffered_write(iocb, iovp, nr_segs, -			pos, &iocb->ki_pos, count, ret); +			pos, &iocb->ki_pos, count, 0); +  	/* -	 * if we just got an ENOSPC, flush the inode now we aren't holding any -	 * page locks and retry *once* +	 * If we just got an ENOSPC, try to write back all dirty inodes to +	 * convert delalloc space to free up some of the excess reserved +	 * metadata space.  	 */  	if (ret == -ENOSPC && !enospc) {  		enospc = 1; -		ret = -xfs_flush_pages(ip, 0, -1, 0, FI_NONE); -		if (!ret) -			goto write_retry; +		xfs_flush_inodes(ip->i_mount); +		goto write_retry;  	}  	current->backing_dev_info = NULL; @@ -889,7 +893,7 @@ xfs_dir_open(  	 */  	mode = xfs_ilock_map_shared(ip);  	if (ip->i_d.di_nextents > 0) -		xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); +		xfs_dir2_data_readahead(NULL, ip, 0, -1);  	xfs_iunlock(ip, mode);  	return 0;  }  |