2016-04-12 20:48:13

by Kani, Toshimitsu

[permalink] [raw]
Subject: [PATCH v2 2/5] ext4: call dax_get_unmapped_area() for DAX pmd mappings

To support DAX pmd mappings with unmodified applications,
filesystems need to align an mmap address by the pmd size.

Call dax_get_unmapped_area() from f_op->get_unmapped_area.

Note, there is no change in behavior for a non-DAX file.

Signed-off-by: Toshi Kani <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Cc: Andreas Dilger <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Ross Zwisler <[email protected]>
Cc: <[email protected]>
---
fs/ext4/file.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index fa2208b..2abc57b 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -708,6 +708,9 @@ const struct file_operations ext4_file_operations = {
.open = ext4_file_open,
.release = ext4_release_file,
.fsync = ext4_sync_file,
+#ifdef CONFIG_FS_DAX
+ .get_unmapped_area = dax_get_unmapped_area,
+#endif
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = ext4_fallocate,


2016-04-12 20:39:31

by Kani, Toshimitsu

[permalink] [raw]
Subject: [PATCH v2 4/5] ext2: call dax_get_unmapped_area() for DAX pmd mappings

To support DAX pmd mappings with unmodified applications,
filesystems need to align an mmap address by the pmd size.

Call dax_get_unmapped_area() from f_op->get_unmapped_area.

Note, there is no change in behavior for a non-DAX file.

Signed-off-by: Toshi Kani <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Ross Zwisler <[email protected]>
Cc: <[email protected]>
---
fs/ext2/file.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index c1400b1..f1b8006 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -172,6 +172,9 @@ const struct file_operations ext2_file_operations = {
.open = dquot_file_open,
.release = ext2_release_file,
.fsync = ext2_fsync,
+#ifdef CONFIG_FS_DAX
+ .get_unmapped_area = dax_get_unmapped_area,
+#endif
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
};

2016-04-13 03:01:56

by Matthew Wilcox

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] ext4: call dax_get_unmapped_area() for DAX pmd mappings

On Tue, Apr 12, 2016 at 02:39:29PM -0600, Toshi Kani wrote:
> To support DAX pmd mappings with unmodified applications,
> filesystems need to align an mmap address by the pmd size.

> @@ -708,6 +708,9 @@ const struct file_operations ext4_file_operations = {
> .open = ext4_file_open,
> .release = ext4_release_file,
> .fsync = ext4_sync_file,
> +#ifdef CONFIG_FS_DAX
> + .get_unmapped_area = dax_get_unmapped_area,
> +#endif
> .splice_read = generic_file_splice_read,
> .splice_write = iter_file_splice_write,
> .fallocate = ext4_fallocate,

Could you do something like:

#ifdef CONFIG_FS_DAX
struct page *read_dax_sector(struct block_device *bdev, sector_t n);
+unsigned long dax_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags);
#else
static inline struct page *read_dax_sector(struct block_device *bdev,
sector_t n)
{
return ERR_PTR(-ENXIO);
}
+#define dax_get_unmapped_area NULL
#endif

in patch 1/5. Then there's no need for the ifdefs in each filesystem.

2016-04-13 15:08:36

by Kani, Toshimitsu

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] ext4: call dax_get_unmapped_area() for DAX pmd mappings

On Tue, 2016-04-12 at 23:01 -0400, Matthew Wilcox wrote:
> On Tue, Apr 12, 2016 at 02:39:29PM -0600, Toshi Kani wrote:
> >
> > To support DAX pmd mappings with unmodified applications,
> > filesystems need to align an mmap address by the pmd size.
> >
> > @@ -708,6 +708,9 @@ const struct file_operations ext4_file_operations =
> > {
> >   .open = ext4_file_open,
> >   .release = ext4_release_file,
> >   .fsync = ext4_sync_file,
> > +#ifdef CONFIG_FS_DAX
> > + .get_unmapped_area = dax_get_unmapped_area,
> > +#endif
> >   .splice_read = generic_file_splice_read,
> >   .splice_write = iter_file_splice_write,
> >   .fallocate = ext4_fallocate,
>
> Could you do something like:
>
>  #ifdef CONFIG_FS_DAX
>  struct page *read_dax_sector(struct block_device *bdev, sector_t n);
> +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long
> addr,
> +               unsigned long len, unsigned long pgoff, unsigned long
> flags);
>  #else
>  static inline struct page *read_dax_sector(struct block_device *bdev,
>                  sector_t n)
>  {
>          return ERR_PTR(-ENXIO);
>  }
> +#define dax_get_unmapped_area NULL
>  #endif
>
> in patch 1/5.  Then there's no need for the ifdefs in each filesystem.

I thought about it, but I do not think we can use an inline function to an
entry point.

Thanks,
-Toshi

2016-04-13 18:22:49

by Matthew Wilcox

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] ext4: call dax_get_unmapped_area() for DAX pmd mappings

On Wed, Apr 13, 2016 at 09:08:36AM -0600, Toshi Kani wrote:
> > Could you do something like:
> >
> > ?#ifdef CONFIG_FS_DAX
> > ?struct page *read_dax_sector(struct block_device *bdev, sector_t n);
> > +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long
> > addr,
> > +???????????????unsigned long len, unsigned long pgoff, unsigned long
> > flags);
> > ?#else
> > ?static inline struct page *read_dax_sector(struct block_device *bdev,
> > ?????????????????sector_t n)
> > ?{
> > ?????????return ERR_PTR(-ENXIO);
> > ?}
> > +#define dax_get_unmapped_area NULL
> > ?#endif
> >
> > in patch 1/5.??Then there's no need for the ifdefs in each filesystem.
>
> I thought about it, but I do not think we can use an inline function to an
> entry point.

That's not an inline function. It's just NULL. So after the preprocessor
is done with it, it just looks like:

.get_unmapped_area = NULL,

and it won't be called by get_unmapped_area().

2016-04-13 18:52:44

by Kani, Toshimitsu

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] ext4: call dax_get_unmapped_area() for DAX pmd mappings

On Wed, 2016-04-13 at 14:22 -0400, Matthew Wilcox wrote:
> On Wed, Apr 13, 2016 at 09:08:36AM -0600, Toshi Kani wrote:
> >
> > >
> > > Could you do something like:
> > >
> > >  #ifdef CONFIG_FS_DAX
> > >  struct page *read_dax_sector(struct block_device *bdev, sector_t n);
> > > +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long
> > > addr,
> > > +               unsigned long len, unsigned long pgoff, unsigned long
> > > flags);
> > >  #else
> > >  static inline struct page *read_dax_sector(struct block_device
> > > *bdev,
> > >                  sector_t n)
> > >  {
> > >          return ERR_PTR(-ENXIO);
> > >  }
> > > +#define dax_get_unmapped_area NULL
> > >  #endif
> > >
> > > in patch 1/5.  Then there's no need for the ifdefs in each
> > > filesystem.
> >
> > I thought about it, but I do not think we can use an inline function to
> > an entry point.
>
> That's not an inline function.  It's just NULL.  So after the
> preprocessor is done with it, it just looks like:
>
> .get_unmapped_area = NULL,
>
> and it won't be called by get_unmapped_area().

Oh, I see. Good idea. I will do that.

Thanks,
-Toshi