diff options
Diffstat (limited to 'fs/xfs/xfs_iops.c')
| -rw-r--r-- | fs/xfs/xfs_iops.c | 70 | 
1 files changed, 48 insertions, 22 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index fe285d123d69..8afe69ca188b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -20,6 +20,7 @@  #include "xfs_symlink.h"  #include "xfs_dir2.h"  #include "xfs_iomap.h" +#include "xfs_error.h"  #include <linux/xattr.h>  #include <linux/posix_acl.h> @@ -470,20 +471,57 @@ xfs_vn_get_link_inline(  	struct inode		*inode,  	struct delayed_call	*done)  { +	struct xfs_inode	*ip = XFS_I(inode);  	char			*link; -	ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE); +	ASSERT(ip->i_df.if_flags & XFS_IFINLINE);  	/*  	 * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if  	 * if_data is junk.  	 */ -	link = XFS_I(inode)->i_df.if_u1.if_data; -	if (!link) +	link = ip->i_df.if_u1.if_data; +	if (XFS_IS_CORRUPT(ip->i_mount, !link))  		return ERR_PTR(-EFSCORRUPTED);  	return link;  } +static uint32_t +xfs_stat_blksize( +	struct xfs_inode	*ip) +{ +	struct xfs_mount	*mp = ip->i_mount; + +	/* +	 * If the file blocks are being allocated from a realtime volume, then +	 * always return the realtime extent size. +	 */ +	if (XFS_IS_REALTIME_INODE(ip)) +		return xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; + +	/* +	 * Allow large block sizes to be reported to userspace programs if the +	 * "largeio" mount option is used. +	 * +	 * If compatibility mode is specified, simply return the basic unit of +	 * caching so that we don't get inefficient read/modify/write I/O from +	 * user apps. Otherwise.... +	 * +	 * If the underlying volume is a stripe, then return the stripe width in +	 * bytes as the recommended I/O size. It is not a stripe and we've set a +	 * default buffered I/O size, return that, otherwise return the compat +	 * default. +	 */ +	if (mp->m_flags & XFS_MOUNT_LARGEIO) { +		if (mp->m_swidth) +			return mp->m_swidth << mp->m_sb.sb_blocklog; +		if (mp->m_flags & XFS_MOUNT_ALLOCSIZE) +			return 1U << mp->m_allocsize_log; +	} + +	return PAGE_SIZE; +} +  STATIC int  xfs_vn_getattr(  	const struct path	*path, @@ -516,8 +554,7 @@ xfs_vn_getattr(  	if (ip->i_d.di_version == 3) {  		if (request_mask & STATX_BTIME) {  			stat->result_mask |= STATX_BTIME; -			stat->btime.tv_sec = ip->i_d.di_crtime.t_sec; -			stat->btime.tv_nsec = ip->i_d.di_crtime.t_nsec; +			stat->btime = ip->i_d.di_crtime;  		}  	} @@ -543,16 +580,7 @@ xfs_vn_getattr(  		stat->rdev = inode->i_rdev;  		break;  	default: -		if (XFS_IS_REALTIME_INODE(ip)) { -			/* -			 * If the file blocks are being allocated from a -			 * realtime volume, then return the inode's realtime -			 * extent size or the realtime volume's extent size. -			 */ -			stat->blksize = -				xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; -		} else -			stat->blksize = xfs_preferred_iosize(mp); +		stat->blksize = xfs_stat_blksize(ip);  		stat->rdev = 0;  		break;  	} @@ -664,7 +692,7 @@ xfs_setattr_nonsize(  		ASSERT(gdqp == NULL);  		error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid),  					   xfs_kgid_to_gid(gid), -					   xfs_get_projid(ip), +					   ip->i_d.di_projid,  					   qflags, &udqp, &gdqp, NULL);  		if (error)  			return error; @@ -883,10 +911,10 @@ xfs_setattr_size(  	if (newsize > oldsize) {  		trace_xfs_zero_eof(ip, oldsize, newsize - oldsize);  		error = iomap_zero_range(inode, oldsize, newsize - oldsize, -				&did_zeroing, &xfs_iomap_ops); +				&did_zeroing, &xfs_buffered_write_iomap_ops);  	} else {  		error = iomap_truncate_page(inode, newsize, &did_zeroing, -				&xfs_iomap_ops); +				&xfs_buffered_write_iomap_ops);  	}  	if (error) @@ -1114,7 +1142,7 @@ xfs_vn_fiemap(  				&xfs_xattr_iomap_ops);  	} else {  		error = iomap_fiemap(inode, fieinfo, start, length, -				&xfs_iomap_ops); +				&xfs_read_iomap_ops);  	}  	xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); @@ -1227,7 +1255,7 @@ xfs_inode_supports_dax(  		return false;  	/* Device has to support DAX too. */ -	return xfs_find_daxdev_for_inode(VFS_I(ip)) != NULL; +	return xfs_inode_buftarg(ip)->bt_daxdev != NULL;  }  STATIC void @@ -1290,9 +1318,7 @@ xfs_setup_inode(  		lockdep_set_class(&inode->i_rwsem,  				  &inode->i_sb->s_type->i_mutex_dir_key);  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); -		ip->d_ops = ip->i_mount->m_dir_inode_ops;  	} else { -		ip->d_ops = ip->i_mount->m_nondir_inode_ops;  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);  	}  |