From: Darrick J. Wong <darrick.wong@oracle.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 4/7] vfs: Add iomap_seek_hole_data helper
Date: Mon, 19 Jun 2017 10:32:32 -0700 [thread overview]
Message-ID: <20170619173232.GA4730@birch.djwong.org> (raw)
In-Reply-To: <1497624680-16685-5-git-send-email-agruenba@redhat.com>
On Fri, Jun 16, 2017 at 04:51:17PM +0200, Andreas Gruenbacher wrote:
> Filesystems can use this for implementing lseek SEEK_HOLE / SEEK_DATA
> support via iomap.
>
> The __iomap_seek_hole_data helper takes an additional size argument and
> doesn't reposition the file offset; this is for internal use for xfs
> quota files which don't maintain the inode size.
>
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> ---
> fs/iomap.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/iomap.h | 6 ++++
> 2 files changed, 87 insertions(+)
>
> diff --git a/fs/iomap.c b/fs/iomap.c
> index 4b10892..cf01694 100644
> --- a/fs/iomap.c
> +++ b/fs/iomap.c
> @@ -584,6 +584,87 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
> }
> EXPORT_SYMBOL_GPL(iomap_fiemap);
>
> +static loff_t
> +iomap_seek_hole_actor(struct inode *inode, loff_t offset, loff_t length,
> + void *data, struct iomap *iomap)
> +{
> + if (iomap->type == IOMAP_HOLE)
Echoing Dave's comments further on (sorry, I tend to read the patchset but
reply in reverse order, distractions notwithstanding), for SEEK_{HOLE,DATA}
you'd want to test for type == IOMAP_HOLE || type == IOMAP_UNWRITTEN since
unwritten (i.e. fallocated) areas are treated as holes.
--D
> + return 0;
> + return iomap->offset + iomap->length - offset;
> +}
> +
> +static loff_t
> +iomap_seek_data_actor(struct inode *inode, loff_t offset, loff_t length,
> + void *data, struct iomap *iomap)
> +{
> + if (iomap->type != IOMAP_HOLE)
> + return 0;
> + return iomap->offset + iomap->length - offset;
> +}
> +
> +loff_t
> +__iomap_seek_hole_data(struct inode *inode, loff_t offset, loff_t size,
> + int whence, const struct iomap_ops *ops)
> +{
> + static loff_t (*actor)(struct inode *, loff_t, loff_t, void *,
> + struct iomap *);
> + loff_t len = size - offset;
> + loff_t ret;
> +
> + /* Nothing to be found beyond the end of the file. */
> + if (len <= 0)
> + return -ENXIO;
> +
> + switch(whence) {
> + case SEEK_HOLE:
> + actor = iomap_seek_hole_actor;
> + break;
> +
> + case SEEK_DATA:
> + actor = iomap_seek_data_actor;
> + break;
> + }
> +
> + while (len > 0) {
> + ret = iomap_apply(inode, offset, len, IOMAP_REPORT, ops,
> + NULL, actor);
> + if (ret <= 0) {
> + if (ret < 0)
> + return ret;
> + break;
> + }
> + offset += ret;
> + len -= ret;
> + }
> +
> + if (len <= 0) {
> + /* There is an implicit hole at the end of the file. */
> + if (whence != SEEK_HOLE)
> + offset = -ENXIO;
> +
> + /* The last segment can extend beyond the end of the file. */
> + if (offset > size)
> + offset = size;
> + }
> +
> + return offset;
> +}
> +EXPORT_SYMBOL_GPL(__iomap_seek_hole_data);
> +
> +loff_t
> +iomap_seek_hole_data(struct file *file, loff_t offset, int whence,
> + const struct iomap_ops *ops)
> +{
> + struct inode *inode = file->f_mapping->host;
> +
> + offset = __iomap_seek_hole_data(inode, offset, i_size_read(inode),
> + whence, ops);
> + if (offset <= 0)
> + return offset;
> + return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
> +}
> +EXPORT_SYMBOL_GPL(iomap_seek_hole_data);
> +
> /*
> * Private flags for iomap_dio, must not overlap with the public ones in
> * iomap.h:
> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
> index 9d64933..49b6ec0 100644
> --- a/include/linux/iomap.h
> +++ b/include/linux/iomap.h
> @@ -85,6 +85,12 @@ int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops);
> int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
> loff_t start, loff_t len, const struct iomap_ops *ops);
>
> +struct file;
> +loff_t __iomap_seek_hole_data(struct inode *inode, loff_t pos, loff_t size,
> + int whence, const struct iomap_ops *ops);
> +loff_t iomap_seek_hole_data(struct file *file, loff_t pos,
> + int whence, const struct iomap_ops *ops);
> +
> /*
> * Flags for direct I/O ->end_io:
> */
> --
> 2.7.5
>
WARNING: multiple messages have this Message-ID (diff)
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Andreas Gruenbacher <agruenba@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, Bob Peterson <rpeterso@redhat.com>,
linux-xfs@vger.kernel.org, cluster-devel@redhat.com
Subject: Re: [PATCH 4/7] vfs: Add iomap_seek_hole_data helper
Date: Mon, 19 Jun 2017 10:32:32 -0700 [thread overview]
Message-ID: <20170619173232.GA4730@birch.djwong.org> (raw)
In-Reply-To: <1497624680-16685-5-git-send-email-agruenba@redhat.com>
On Fri, Jun 16, 2017 at 04:51:17PM +0200, Andreas Gruenbacher wrote:
> Filesystems can use this for implementing lseek SEEK_HOLE / SEEK_DATA
> support via iomap.
>
> The __iomap_seek_hole_data helper takes an additional size argument and
> doesn't reposition the file offset; this is for internal use for xfs
> quota files which don't maintain the inode size.
>
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> ---
> fs/iomap.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/iomap.h | 6 ++++
> 2 files changed, 87 insertions(+)
>
> diff --git a/fs/iomap.c b/fs/iomap.c
> index 4b10892..cf01694 100644
> --- a/fs/iomap.c
> +++ b/fs/iomap.c
> @@ -584,6 +584,87 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
> }
> EXPORT_SYMBOL_GPL(iomap_fiemap);
>
> +static loff_t
> +iomap_seek_hole_actor(struct inode *inode, loff_t offset, loff_t length,
> + void *data, struct iomap *iomap)
> +{
> + if (iomap->type == IOMAP_HOLE)
Echoing Dave's comments further on (sorry, I tend to read the patchset but
reply in reverse order, distractions notwithstanding), for SEEK_{HOLE,DATA}
you'd want to test for type == IOMAP_HOLE || type == IOMAP_UNWRITTEN since
unwritten (i.e. fallocated) areas are treated as holes.
--D
> + return 0;
> + return iomap->offset + iomap->length - offset;
> +}
> +
> +static loff_t
> +iomap_seek_data_actor(struct inode *inode, loff_t offset, loff_t length,
> + void *data, struct iomap *iomap)
> +{
> + if (iomap->type != IOMAP_HOLE)
> + return 0;
> + return iomap->offset + iomap->length - offset;
> +}
> +
> +loff_t
> +__iomap_seek_hole_data(struct inode *inode, loff_t offset, loff_t size,
> + int whence, const struct iomap_ops *ops)
> +{
> + static loff_t (*actor)(struct inode *, loff_t, loff_t, void *,
> + struct iomap *);
> + loff_t len = size - offset;
> + loff_t ret;
> +
> + /* Nothing to be found beyond the end of the file. */
> + if (len <= 0)
> + return -ENXIO;
> +
> + switch(whence) {
> + case SEEK_HOLE:
> + actor = iomap_seek_hole_actor;
> + break;
> +
> + case SEEK_DATA:
> + actor = iomap_seek_data_actor;
> + break;
> + }
> +
> + while (len > 0) {
> + ret = iomap_apply(inode, offset, len, IOMAP_REPORT, ops,
> + NULL, actor);
> + if (ret <= 0) {
> + if (ret < 0)
> + return ret;
> + break;
> + }
> + offset += ret;
> + len -= ret;
> + }
> +
> + if (len <= 0) {
> + /* There is an implicit hole at the end of the file. */
> + if (whence != SEEK_HOLE)
> + offset = -ENXIO;
> +
> + /* The last segment can extend beyond the end of the file. */
> + if (offset > size)
> + offset = size;
> + }
> +
> + return offset;
> +}
> +EXPORT_SYMBOL_GPL(__iomap_seek_hole_data);
> +
> +loff_t
> +iomap_seek_hole_data(struct file *file, loff_t offset, int whence,
> + const struct iomap_ops *ops)
> +{
> + struct inode *inode = file->f_mapping->host;
> +
> + offset = __iomap_seek_hole_data(inode, offset, i_size_read(inode),
> + whence, ops);
> + if (offset <= 0)
> + return offset;
> + return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
> +}
> +EXPORT_SYMBOL_GPL(iomap_seek_hole_data);
> +
> /*
> * Private flags for iomap_dio, must not overlap with the public ones in
> * iomap.h:
> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
> index 9d64933..49b6ec0 100644
> --- a/include/linux/iomap.h
> +++ b/include/linux/iomap.h
> @@ -85,6 +85,12 @@ int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops);
> int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
> loff_t start, loff_t len, const struct iomap_ops *ops);
>
> +struct file;
> +loff_t __iomap_seek_hole_data(struct inode *inode, loff_t pos, loff_t size,
> + int whence, const struct iomap_ops *ops);
> +loff_t iomap_seek_hole_data(struct file *file, loff_t pos,
> + int whence, const struct iomap_ops *ops);
> +
> /*
> * Flags for direct I/O ->end_io:
> */
> --
> 2.7.5
>
next prev parent reply other threads:[~2017-06-19 17:32 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-16 14:51 [Cluster-devel] [PATCH 0/7] lseek SEEK_HOLE / SEEK_DATA via iomap Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 1/7] GFS2: Make height info part of metapath Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 2/7] GFS2: Implement iomap for block_map Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 3/7] GFS2: Switch fiemap implementation to use iomap Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 4/7] vfs: Add iomap_seek_hole_data helper Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-19 17:32 ` Darrick J. Wong [this message]
2017-06-19 17:32 ` Darrick J. Wong
2017-06-16 14:51 ` [Cluster-devel] [PATCH 5/7] gfs2: Implement lseek SEEK_HOLE / SEEK_DATA via iomap Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 6/7] xfs: Switch to iomap for lseek SEEK_HOLE / SEEK_DATA Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-17 23:57 ` [Cluster-devel] " Dave Chinner
2017-06-17 23:57 ` Dave Chinner
2017-06-19 22:16 ` [Cluster-devel] " Andreas Gruenbacher
2017-06-19 22:16 ` Andreas Gruenbacher
2017-06-16 14:51 ` [Cluster-devel] [PATCH 7/7] xfs: Switch to iomap for seeking in quota files Andreas Gruenbacher
2017-06-16 14:51 ` Andreas Gruenbacher
2017-06-16 15:30 ` [Cluster-devel] " Darrick J. Wong
2017-06-16 15:30 ` Darrick J. Wong
2017-06-20 6:31 ` [Cluster-devel] " Christoph Hellwig
2017-06-20 6:31 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170619173232.GA4730@birch.djwong.org \
--to=darrick.wong@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.