diff mbox series

[15/20] fiemap: Start using new callback from fiemap_ctx

Message ID 20181030131823.29040-16-cmaiolino@redhat.com (mailing list archive)
State New, archived
Headers show
Series New ->fiemap infrastructure and ->bmap removal | expand

Commit Message

Carlos Maiolino Oct. 30, 2018, 1:18 p.m. UTC
Now that fiemap methods are updated to work based on the new fiemap_ctx
structure, update the code to use the new callback.
The current fiemap_fill_next_extent will be used for user calls of
->fiemap methods, as its done today, but passed in as a callback to
fiemap_ctx. So, rename it to ifemap_fill_usr_extent().

The 'new' fiemap_fill_next_extent() will now be just a helper to call
fiemap_ctx callback.

Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
 fs/ioctl.c         | 42 +++++++++++++++++++++++++-----------------
 include/linux/fs.h |  2 +-
 2 files changed, 26 insertions(+), 18 deletions(-)

Comments

Andreas Dilger Nov. 5, 2018, 10:14 p.m. UTC | #1
On Oct 30, 2018, at 7:18 AM, Carlos Maiolino <cmaiolino@redhat.com> wrote:
> 
> Now that fiemap methods are updated to work based on the new fiemap_ctx
> structure, update the code to use the new callback.
> The current fiemap_fill_next_extent will be used for user calls of
> ->fiemap methods, as its done today, but passed in as a callback to
> fiemap_ctx. So, rename it to ifemap_fill_usr_extent().

Minor typo here s/ifemap/fiemap/

Couldn't this series have (mostly?) been achieved by just adding the
callback to fiemap_extent_info and using that everywhere?

Cheers, Andreas

> The 'new' fiemap_fill_next_extent() will now be just a helper to call
> fiemap_ctx callback.
> 
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
> fs/ioctl.c         | 42 +++++++++++++++++++++++++-----------------
> include/linux/fs.h |  2 +-
> 2 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 27f79b29cb07..85a7aec40e3d 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -68,25 +68,10 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
> 	return put_user(res, p);
> }
> 
> -/**
> - * fiemap_fill_next_extent - Fiemap helper function
> - * @fieinfo:	Fiemap context passed into ->fiemap
> - * @logical:	Extent logical start offset, in bytes
> - * @phys:	Extent physical start offset, in bytes
> - * @len:	Extent length, in bytes
> - * @flags:	FIEMAP_EXTENT flags that describe this extent
> - *
> - * Called from file system ->fiemap callback. Will populate extent
> - * info as passed in via arguments and copy to user memory. On
> - * success, extent count on fieinfo is incremented.
> - *
> - * Returns 0 on success, -errno on error, 1 if this was the last
> - * extent that will fit in user array.
> - */
> #define SET_UNKNOWN_FLAGS	(FIEMAP_EXTENT_DELALLOC)
> #define SET_NO_UNMOUNTED_IO_FLAGS	(FIEMAP_EXTENT_DATA_ENCRYPTED)
> #define SET_NOT_ALIGNED_FLAGS	(FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
> -int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> +int fiemap_fill_usr_extent(struct fiemap_ctx *f_ctx, u64 logical,
> 			    u64 phys, u64 len, u32 flags)
> {
> 	struct fiemap_extent_info *fieinfo = f_ctx->fc_data;
> @@ -124,8 +109,29 @@ int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> 		return 1;
> 	return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
> }
> -EXPORT_SYMBOL(fiemap_fill_next_extent);
> 
> +/**
> + * fiemap_fill_next_extent - Fiemap helper function
> + * @fieinfo:	Fiemap context passed into ->fiemap
> + * @logical:	Extent logical start offset, in bytes
> + * @phys:	Extent physical start offset, in bytes
> + * @len:	Extent length, in bytes
> + * @flags:	FIEMAP_EXTENT flags that describe this extent
> + *
> + * Called from file system ->fiemap callback. Will populate extent
> + * info as passed in via arguments and copy to user memory. On
> + * success, extent count on fieinfo is incremented.
> + *
> + * Returns 0 on success, -errno on error, 1 if this was the last
> + * extent that will fit in user array.
> + */
> +
> +int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> +			    u64 phys, u64 len, u32 flags)
> +{
> +	return f_ctx->fc_cb(f_ctx, logical, phys, len, flags);
> +}
> +EXPORT_SYMBOL(fiemap_fill_next_extent);
> /**
>  * fiemap_check_flags - check validity of requested flags for fiemap
>  * @fieinfo:	Fiemap context passed into ->fiemap
> @@ -208,6 +214,8 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
> 	f_ctx.fc_start = fiemap.fm_start;
> 	f_ctx.fc_len = len;
> 
> +	f_ctx.fc_cb = fiemap_fill_usr_extent;
> +
> 	if (fiemap.fm_extent_count != 0 &&
> 	    !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
> 		       fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 945cfb3e06e4..9a538bc0dac2 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1704,7 +1704,7 @@ typedef int (*fiemap_fill_cb)(struct fiemap_ctx *f_ctx, u64 logical,
> struct fiemap_ctx {
> 	unsigned int fc_flags;	/* Flags as passed from user */
> 	void *fc_data;
> -	fiemap_fill_cb fc_cb; /* Unused by now */
> +	fiemap_fill_cb fc_cb;
> 	u64 fc_start;
> 	u64 fc_len;
> };
> --
> 2.17.1
> 


Cheers, Andreas
Carlos Maiolino Nov. 6, 2018, 8:52 a.m. UTC | #2
On Mon, Nov 05, 2018 at 03:14:02PM -0700, Andreas Dilger wrote:
> On Oct 30, 2018, at 7:18 AM, Carlos Maiolino <cmaiolino@redhat.com> wrote:
> > 
> > Now that fiemap methods are updated to work based on the new fiemap_ctx
> > structure, update the code to use the new callback.
> > The current fiemap_fill_next_extent will be used for user calls of
> > ->fiemap methods, as its done today, but passed in as a callback to
> > fiemap_ctx. So, rename it to ifemap_fill_usr_extent().
> 
> Minor typo here s/ifemap/fiemap/
> 
> Couldn't this series have (mostly?) been achieved by just adding the
> callback to fiemap_extent_info and using that everywhere?

Not really, because fiemap_extent_info has (had now) a userspace pointer, which
isn't used in FIBMAP calls in later patches, so the idea of using callbacks
started as a need to use different code workflow, depending on the user of (now
deprecated) fiemap_extent_info

> 
> Cheers, Andreas
> 
> > The 'new' fiemap_fill_next_extent() will now be just a helper to call
> > fiemap_ctx callback.
> > 
> > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> > ---
> > fs/ioctl.c         | 42 +++++++++++++++++++++++++-----------------
> > include/linux/fs.h |  2 +-
> > 2 files changed, 26 insertions(+), 18 deletions(-)
> > 
> > diff --git a/fs/ioctl.c b/fs/ioctl.c
> > index 27f79b29cb07..85a7aec40e3d 100644
> > --- a/fs/ioctl.c
> > +++ b/fs/ioctl.c
> > @@ -68,25 +68,10 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
> > 	return put_user(res, p);
> > }
> > 
> > -/**
> > - * fiemap_fill_next_extent - Fiemap helper function
> > - * @fieinfo:	Fiemap context passed into ->fiemap
> > - * @logical:	Extent logical start offset, in bytes
> > - * @phys:	Extent physical start offset, in bytes
> > - * @len:	Extent length, in bytes
> > - * @flags:	FIEMAP_EXTENT flags that describe this extent
> > - *
> > - * Called from file system ->fiemap callback. Will populate extent
> > - * info as passed in via arguments and copy to user memory. On
> > - * success, extent count on fieinfo is incremented.
> > - *
> > - * Returns 0 on success, -errno on error, 1 if this was the last
> > - * extent that will fit in user array.
> > - */
> > #define SET_UNKNOWN_FLAGS	(FIEMAP_EXTENT_DELALLOC)
> > #define SET_NO_UNMOUNTED_IO_FLAGS	(FIEMAP_EXTENT_DATA_ENCRYPTED)
> > #define SET_NOT_ALIGNED_FLAGS	(FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
> > -int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> > +int fiemap_fill_usr_extent(struct fiemap_ctx *f_ctx, u64 logical,
> > 			    u64 phys, u64 len, u32 flags)
> > {
> > 	struct fiemap_extent_info *fieinfo = f_ctx->fc_data;
> > @@ -124,8 +109,29 @@ int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> > 		return 1;
> > 	return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
> > }
> > -EXPORT_SYMBOL(fiemap_fill_next_extent);
> > 
> > +/**
> > + * fiemap_fill_next_extent - Fiemap helper function
> > + * @fieinfo:	Fiemap context passed into ->fiemap
> > + * @logical:	Extent logical start offset, in bytes
> > + * @phys:	Extent physical start offset, in bytes
> > + * @len:	Extent length, in bytes
> > + * @flags:	FIEMAP_EXTENT flags that describe this extent
> > + *
> > + * Called from file system ->fiemap callback. Will populate extent
> > + * info as passed in via arguments and copy to user memory. On
> > + * success, extent count on fieinfo is incremented.
> > + *
> > + * Returns 0 on success, -errno on error, 1 if this was the last
> > + * extent that will fit in user array.
> > + */
> > +
> > +int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> > +			    u64 phys, u64 len, u32 flags)
> > +{
> > +	return f_ctx->fc_cb(f_ctx, logical, phys, len, flags);
> > +}
> > +EXPORT_SYMBOL(fiemap_fill_next_extent);
> > /**
> >  * fiemap_check_flags - check validity of requested flags for fiemap
> >  * @fieinfo:	Fiemap context passed into ->fiemap
> > @@ -208,6 +214,8 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
> > 	f_ctx.fc_start = fiemap.fm_start;
> > 	f_ctx.fc_len = len;
> > 
> > +	f_ctx.fc_cb = fiemap_fill_usr_extent;
> > +
> > 	if (fiemap.fm_extent_count != 0 &&
> > 	    !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
> > 		       fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
> > diff --git a/include/linux/fs.h b/include/linux/fs.h
> > index 945cfb3e06e4..9a538bc0dac2 100644
> > --- a/include/linux/fs.h
> > +++ b/include/linux/fs.h
> > @@ -1704,7 +1704,7 @@ typedef int (*fiemap_fill_cb)(struct fiemap_ctx *f_ctx, u64 logical,
> > struct fiemap_ctx {
> > 	unsigned int fc_flags;	/* Flags as passed from user */
> > 	void *fc_data;
> > -	fiemap_fill_cb fc_cb; /* Unused by now */
> > +	fiemap_fill_cb fc_cb;
> > 	u64 fc_start;
> > 	u64 fc_len;
> > };
> > --
> > 2.17.1
> > 
> 
> 
> Cheers, Andreas
> 
> 
> 
> 
>
Christoph Hellwig Nov. 16, 2018, 3:55 p.m. UTC | #3
On Tue, Nov 06, 2018 at 09:52:03AM +0100, Carlos Maiolino wrote:
> Not really, because fiemap_extent_info has (had now) a userspace pointer, which
> isn't used in FIBMAP calls in later patches, so the idea of using callbacks
> started as a need to use different code workflow, depending on the user of (now
> deprecated) fiemap_extent_info

Well, we could also change that member of fiemap_extent_info if we
really wanted to.  Not sure that would be the better route, though.
Christoph Hellwig Nov. 16, 2018, 3:57 p.m. UTC | #4
> +int fiemap_fill_usr_extent(struct fiemap_ctx *f_ctx, u64 logical,

Please spell out user.

> +int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> +			    u64 phys, u64 len, u32 flags)
> +{
> +	return f_ctx->fc_cb(f_ctx, logical, phys, len, flags);
> +}
> +EXPORT_SYMBOL(fiemap_fill_next_extent);

Do we really need this wrapper?  Which reminds me that we usually
pass the callbacks as direct function arguments.  Any good reason it
is in the context here?
Carlos Maiolino Nov. 19, 2018, 12:26 p.m. UTC | #5
On Fri, Nov 16, 2018 at 04:55:42PM +0100, Christoph Hellwig wrote:
> On Tue, Nov 06, 2018 at 09:52:03AM +0100, Carlos Maiolino wrote:
> > Not really, because fiemap_extent_info has (had now) a userspace pointer, which
> > isn't used in FIBMAP calls in later patches, so the idea of using callbacks
> > started as a need to use different code workflow, depending on the user of (now
> > deprecated) fiemap_extent_info
> 
> Well, we could also change that member of fiemap_extent_info if we
> really wanted to.  Not sure that would be the better route, though.

I think there are some downsides in keep using fiemap_extent_info. I'd rather
prefer use this new fiemap_ctx, which we can use to embed most of the arguments
needed for fiemap, like the flags which were passed separated.
At all, most of the fields would fit either in fiemap_extent_info, or the new
fiemap_ctx. I'd prefer the latter, due simplicity.
We could probably simplify it using the void pointer directly into
fiemap_extent_info and using flags to discern between user/kernel space pointer.
But that would drop one of the goals of this patchset, which is adding a new and
better interface for FIEMAP. Preferentially, I'd stick with fiemap_ctx.

Cheers and thanks for the review
Carlos Maiolino Nov. 19, 2018, 12:37 p.m. UTC | #6
On Fri, Nov 16, 2018 at 04:57:21PM +0100, Christoph Hellwig wrote:
> > +int fiemap_fill_usr_extent(struct fiemap_ctx *f_ctx, u64 logical,
> 
> Please spell out user.

Sure, will do.

> 
> > +int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
> > +			    u64 phys, u64 len, u32 flags)
> > +{
> > +	return f_ctx->fc_cb(f_ctx, logical, phys, len, flags);
> > +}
> > +EXPORT_SYMBOL(fiemap_fill_next_extent);
> 
> Do we really need this wrapper?  Which reminds me that we usually
> pass the callbacks as direct function arguments.  Any good reason it
> is in the context here?

The reason I left the wrapper is to avoid replacing all
fiemap_fill_next_extent() calls by the callback, may not be the best idea
though.

About using the callback in the context, I thought it would be the easiest way
to pass the callbacks around, without adding a function pointer to many
functions.
The callback is set in ioctl_fiemap() (for user context) or bmap(), if we pass
the callback via function argument, many filesystems would need to juggle around
with the function pointer, once, some of them does not call the
fiemap_fill_next_extent directly from the fiemap method, but into other
sub-functions, for example, in ext4, we would need the function pointer in
ext4_fiemap, and other functions like ext4_fill_fiemap_extents() and
ext4_xattr_fiemap(), etc.

We could even call fiemap_fill_{usr,kernel}_extent() directly from
fiemap_fill_next_extent, and use a flag to differentiate both use cases, but
this will kill the transparent implementation IMHO.
diff mbox series

Patch

diff --git a/fs/ioctl.c b/fs/ioctl.c
index 27f79b29cb07..85a7aec40e3d 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -68,25 +68,10 @@  static int ioctl_fibmap(struct file *filp, int __user *p)
 	return put_user(res, p);
 }
 
-/**
- * fiemap_fill_next_extent - Fiemap helper function
- * @fieinfo:	Fiemap context passed into ->fiemap
- * @logical:	Extent logical start offset, in bytes
- * @phys:	Extent physical start offset, in bytes
- * @len:	Extent length, in bytes
- * @flags:	FIEMAP_EXTENT flags that describe this extent
- *
- * Called from file system ->fiemap callback. Will populate extent
- * info as passed in via arguments and copy to user memory. On
- * success, extent count on fieinfo is incremented.
- *
- * Returns 0 on success, -errno on error, 1 if this was the last
- * extent that will fit in user array.
- */
 #define SET_UNKNOWN_FLAGS	(FIEMAP_EXTENT_DELALLOC)
 #define SET_NO_UNMOUNTED_IO_FLAGS	(FIEMAP_EXTENT_DATA_ENCRYPTED)
 #define SET_NOT_ALIGNED_FLAGS	(FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
-int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
+int fiemap_fill_usr_extent(struct fiemap_ctx *f_ctx, u64 logical,
 			    u64 phys, u64 len, u32 flags)
 {
 	struct fiemap_extent_info *fieinfo = f_ctx->fc_data;
@@ -124,8 +109,29 @@  int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
 		return 1;
 	return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
 }
-EXPORT_SYMBOL(fiemap_fill_next_extent);
 
+/**
+ * fiemap_fill_next_extent - Fiemap helper function
+ * @fieinfo:	Fiemap context passed into ->fiemap
+ * @logical:	Extent logical start offset, in bytes
+ * @phys:	Extent physical start offset, in bytes
+ * @len:	Extent length, in bytes
+ * @flags:	FIEMAP_EXTENT flags that describe this extent
+ *
+ * Called from file system ->fiemap callback. Will populate extent
+ * info as passed in via arguments and copy to user memory. On
+ * success, extent count on fieinfo is incremented.
+ *
+ * Returns 0 on success, -errno on error, 1 if this was the last
+ * extent that will fit in user array.
+ */
+
+int fiemap_fill_next_extent(struct fiemap_ctx *f_ctx, u64 logical,
+			    u64 phys, u64 len, u32 flags)
+{
+	return f_ctx->fc_cb(f_ctx, logical, phys, len, flags);
+}
+EXPORT_SYMBOL(fiemap_fill_next_extent);
 /**
  * fiemap_check_flags - check validity of requested flags for fiemap
  * @fieinfo:	Fiemap context passed into ->fiemap
@@ -208,6 +214,8 @@  static int ioctl_fiemap(struct file *filp, unsigned long arg)
 	f_ctx.fc_start = fiemap.fm_start;
 	f_ctx.fc_len = len;
 
+	f_ctx.fc_cb = fiemap_fill_usr_extent;
+
 	if (fiemap.fm_extent_count != 0 &&
 	    !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
 		       fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 945cfb3e06e4..9a538bc0dac2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1704,7 +1704,7 @@  typedef int (*fiemap_fill_cb)(struct fiemap_ctx *f_ctx, u64 logical,
 struct fiemap_ctx {
 	unsigned int fc_flags;	/* Flags as passed from user */
 	void *fc_data;
-	fiemap_fill_cb fc_cb; /* Unused by now */
+	fiemap_fill_cb fc_cb;
 	u64 fc_start;
 	u64 fc_len;
 };