Re: [PATCH 3/4] xfs: Factor xfs_seek_hole_data into helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri 08-01-16 10:58:57, Eric Sandeen wrote:
> Factor xfs_seek_hole_data into an unlocked helper which takes
> an xfs inode rather than a file for internal use.
> 
> Also allow specification of "end" - the vfs lseek interface is
> defined such that any offset past eof/i_size shall return -ENXIO,
> but we will use this for quota code which does not maintain i_size,
> and we want to be able to SEEK_DATA past i_size as well. So the
> lseek path can send in i_size, and the quota code can determine
> its own ending offset.

This patch looks whitespace damaged making it difficult to read...

								Honza
 
> Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx>
> ---
> fs/xfs/xfs_file.c | 82 ++++++++++++++++++++++++++++++++++++----------------
> fs/xfs/xfs_inode.h | 2 +
> 2 files changed, 59 insertions(+), 25 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index ebe9b82..5dc7113 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -1337,31 +1337,31 @@ out:
> return found;
> }
> 
> -STATIC loff_t
> -xfs_seek_hole_data(
> - struct file *file,
> +/*
> + * caller must lock inode with xfs_ilock_data_map_shared,
> + * can we craft an appropriate ASSERT?
> + *
> + * end is because the VFS-level lseek interface is defined such that any
> + * offset past i_size shall return -ENXIO, but we use this for quota code
> + * which does not maintain i_size, and we want to SEEK_DATA past i_size.
> + */
> +loff_t
> +__xfs_seek_hole_data(
> + struct inode *inode,
> loff_t start,
> + loff_t end,
> int whence)
> {
> - struct inode *inode = file->f_mapping->host;
> struct xfs_inode *ip = XFS_I(inode);
> struct xfs_mount *mp = ip->i_mount;
> loff_t uninitialized_var(offset);
> - xfs_fsize_t isize;
> xfs_fileoff_t fsbno;
> - xfs_filblks_t end;
> - uint lock;
> + xfs_filblks_t lastbno;
> int error;
> 
> - if (XFS_FORCED_SHUTDOWN(mp))
> - return -EIO;
> -
> - lock = xfs_ilock_data_map_shared(ip);
> -
> - isize = i_size_read(inode);
> - if (start >= isize) {
> + if (start >= end) {
> error = -ENXIO;
> - goto out_unlock;
> + goto out_error;
> }
> 
> /*
> @@ -1369,22 +1369,22 @@ xfs_seek_hole_data(
> * by fsbno to the end block of the file.
> */
> fsbno = XFS_B_TO_FSBT(mp, start);
> - end = XFS_B_TO_FSB(mp, isize);
> + lastbno = XFS_B_TO_FSB(mp, end);
> 
> for (;;) {
> struct xfs_bmbt_irec map[2];
> int nmap = 2;
> unsigned int i;
> 
> - error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap,
> + error = xfs_bmapi_read(ip, fsbno, lastbno - fsbno, map, &nmap,
> XFS_BMAPI_ENTIRE);
> if (error)
> - goto out_unlock;
> + goto out_error;
> 
> /* No extents at given offset, must be beyond EOF */
> if (nmap == 0) {
> error = -ENXIO;
> - goto out_unlock;
> + goto out_error;
> }
> 
> for (i = 0; i < nmap; i++) {
> @@ -1426,7 +1426,7 @@ xfs_seek_hole_data(
> * hole at the end of any file).
> */
> if (whence == SEEK_HOLE) {
> - offset = isize;
> + offset = end;
> break;
> }
> /*
> @@ -1434,7 +1434,7 @@ xfs_seek_hole_data(
> */
> ASSERT(whence == SEEK_DATA);
> error = -ENXIO;
> - goto out_unlock;
> + goto out_error;
> }
> 
> ASSERT(i > 1);
> @@ -1445,14 +1445,14 @@ xfs_seek_hole_data(
> */
> fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount;
> start = XFS_FSB_TO_B(mp, fsbno);
> - if (start >= isize) {
> + if (start >= end) {
> if (whence == SEEK_HOLE) {
> - offset = isize;
> + offset = end;
> break;
> }
> ASSERT(whence == SEEK_DATA);
> error = -ENXIO;
> - goto out_unlock;
> + goto out_error;
> }
> }
> 
> @@ -1464,7 +1464,39 @@ out:
> * situation in particular.
> */
> if (whence == SEEK_HOLE)
> - offset = min_t(loff_t, offset, isize);
> + offset = min_t(loff_t, offset, end);
> +
> + return offset;
> +
> +out_error:
> + return error;
> +}
> +
> +STATIC loff_t
> +xfs_seek_hole_data(
> + struct file *file,
> + loff_t start,
> + int whence)
> +{
> + struct inode *inode = file->f_mapping->host;
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> + uint lock;
> + loff_t offset, end;
> + int error = 0;
> +
> + if (XFS_FORCED_SHUTDOWN(mp))
> + return -EIO;
> +
> + lock = xfs_ilock_data_map_shared(ip);
> +
> + end = i_size_read(inode);
> + offset = __xfs_seek_hole_data(inode, start, end, whence);
> + if (offset < 0) {
> + error = offset;
> + goto out_unlock;
> + }
> +
> offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
> 
> out_unlock:
> diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
> index ca9e119..ed7e933 100644
> --- a/fs/xfs/xfs_inode.h
> +++ b/fs/xfs/xfs_inode.h
> @@ -437,6 +437,8 @@ int xfs_update_prealloc_flags(struct xfs_inode *ip,
> int xfs_zero_eof(struct xfs_inode *ip, xfs_off_t offset,
> xfs_fsize_t isize, bool *did_zeroing);
> int xfs_iozero(struct xfs_inode *ip, loff_t pos, size_t count);
> +loff_t __xfs_seek_hole_data(struct inode *inode, loff_t start,
> + loff_t eof, int whence);
> 
> 
> /* from xfs_iops.c */
> -- 
> 1.7.1
> 
> 
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux