diff options
Diffstat (limited to 'fs/xfs/xfs_file.c')
| -rw-r--r-- | fs/xfs/xfs_file.c | 100 | 
1 files changed, 14 insertions, 86 deletions
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 632653e00906..b240ea5241dc 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -24,6 +24,7 @@  #include "xfs_pnfs.h"  #include "xfs_iomap.h"  #include "xfs_reflink.h" +#include "xfs_file.h"  #include <linux/dax.h>  #include <linux/falloc.h> @@ -38,33 +39,19 @@ static const struct vm_operations_struct xfs_file_vm_ops;   * Decide if the given file range is aligned to the size of the fundamental   * allocation unit for the file.   */ -static bool +bool  xfs_is_falloc_aligned(  	struct xfs_inode	*ip,  	loff_t			pos,  	long long int		len)  { -	struct xfs_mount	*mp = ip->i_mount; -	uint64_t		mask; - -	if (XFS_IS_REALTIME_INODE(ip)) { -		if (!is_power_of_2(mp->m_sb.sb_rextsize)) { -			u64	rextbytes; -			u32	mod; - -			rextbytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize); -			div_u64_rem(pos, rextbytes, &mod); -			if (mod) -				return false; -			div_u64_rem(len, rextbytes, &mod); -			return mod == 0; -		} -		mask = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize) - 1; -	} else { -		mask = mp->m_sb.sb_blocksize - 1; -	} +	unsigned int		alloc_unit = xfs_inode_alloc_unitsize(ip); -	return !((pos | len) & mask); +	if (!is_power_of_2(alloc_unit)) +		return isaligned_64(pos, alloc_unit) && +		       isaligned_64(len, alloc_unit); + +	return !((pos | len) & (alloc_unit - 1));  }  /* @@ -861,67 +848,6 @@ xfs_file_write_iter(  	return xfs_file_buffered_write(iocb, from);  } -static void -xfs_wait_dax_page( -	struct inode		*inode) -{ -	struct xfs_inode        *ip = XFS_I(inode); - -	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL); -	schedule(); -	xfs_ilock(ip, XFS_MMAPLOCK_EXCL); -} - -int -xfs_break_dax_layouts( -	struct inode		*inode, -	bool			*retry) -{ -	struct page		*page; - -	xfs_assert_ilocked(XFS_I(inode), XFS_MMAPLOCK_EXCL); - -	page = dax_layout_busy_page(inode->i_mapping); -	if (!page) -		return 0; - -	*retry = true; -	return ___wait_var_event(&page->_refcount, -			atomic_read(&page->_refcount) == 1, TASK_INTERRUPTIBLE, -			0, 0, xfs_wait_dax_page(inode)); -} - -int -xfs_break_layouts( -	struct inode		*inode, -	uint			*iolock, -	enum layout_break_reason reason) -{ -	bool			retry; -	int			error; - -	xfs_assert_ilocked(XFS_I(inode), XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL); - -	do { -		retry = false; -		switch (reason) { -		case BREAK_UNMAP: -			error = xfs_break_dax_layouts(inode, &retry); -			if (error || retry) -				break; -			fallthrough; -		case BREAK_WRITE: -			error = xfs_break_leased_layouts(inode, iolock, &retry); -			break; -		default: -			WARN_ON_ONCE(1); -			error = -EINVAL; -		} -	} while (error == 0 && retry); - -	return error; -} -  /* Does this file, inode, or mount want synchronous writes? */  static inline bool xfs_file_sync_writes(struct file *filp)  { @@ -1230,8 +1156,7 @@ xfs_file_open(  {  	if (xfs_is_shutdown(XFS_M(inode->i_sb)))  		return -EIO; -	file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC | -			FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT; +	file->f_mode |= FMODE_NOWAIT | FMODE_CAN_ODIRECT;  	return generic_file_open(inode, file);  } @@ -1244,7 +1169,9 @@ xfs_dir_open(  	unsigned int	mode;  	int		error; -	error = xfs_file_open(inode, file); +	if (xfs_is_shutdown(ip->i_mount)) +		return -EIO; +	error = generic_file_open(inode, file);  	if (error)  		return error; @@ -1490,7 +1417,6 @@ const struct file_operations xfs_file_operations = {  	.compat_ioctl	= xfs_file_compat_ioctl,  #endif  	.mmap		= xfs_file_mmap, -	.mmap_supported_flags = MAP_SYNC,  	.open		= xfs_file_open,  	.release	= xfs_file_release,  	.fsync		= xfs_file_fsync, @@ -1498,6 +1424,8 @@ const struct file_operations xfs_file_operations = {  	.fallocate	= xfs_file_fallocate,  	.fadvise	= xfs_file_fadvise,  	.remap_file_range = xfs_file_remap_range, +	.fop_flags	= FOP_MMAP_SYNC | FOP_BUFFER_RASYNC | +			  FOP_BUFFER_WASYNC | FOP_DIO_PARALLEL_WRITE,  };  const struct file_operations xfs_dir_file_operations = {  |