Message ID | 20240827020029.620357-1-lihongbo22@huawei.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [-next] nilfs2: support STATX_DIOALIGN for statx file | expand |
Sorry, I send the wrong patch, just ignore this. On 2024/8/27 10:00, Hongbo Li wrote: > Add support for STATX_DIOALIGN to nilfs2, so that direct I/O alignment > restrictions are exposed to userspace in a generic way. > > By default, nilfs2 uses the default getattr implemented at vfs layer, > so we should implement getattr in nilfs2 to fill the dio_xx_align > members. We have done the following test: > > [Before] > ``` > ./statx_test /mnt/nilfs2/testfile > statx(/mnt/nilfs2/test) = 0 > dio mem align:0 > dio offset align:0 > ``` > > [After] > ``` > ./statx_test /mnt/nilfs2/test > statx(/mnt/nilfs2/test) = 0 > dio mem align:512 > dio offset align:512 > ``` > > Signed-off-by: Hongbo Li <lihongbo22@huawei.com> > --- > fs/nilfs2/file.c | 1 + > fs/nilfs2/inode.c | 20 ++++++++++++++++++++ > fs/nilfs2/namei.c | 2 ++ > fs/nilfs2/nilfs.h | 2 ++ > 4 files changed, 25 insertions(+) > > diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c > index 0e3fc5ba33c7..5528918d4b96 100644 > --- a/fs/nilfs2/file.c > +++ b/fs/nilfs2/file.c > @@ -154,6 +154,7 @@ const struct file_operations nilfs_file_operations = { > > const struct inode_operations nilfs_file_inode_operations = { > .setattr = nilfs_setattr, > + .getattr = nilfs_getattr, > .permission = nilfs_permission, > .fiemap = nilfs_fiemap, > .fileattr_get = nilfs_fileattr_get, > diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c > index 7340a01d80e1..7bf062793642 100644 > --- a/fs/nilfs2/inode.c > +++ b/fs/nilfs2/inode.c > @@ -1001,6 +1001,26 @@ int nilfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, > return err; > } > > +int nilfs_getattr(struct mnt_idmap *idmap, const struct path *path, > + struct kstat *stat, u3 request_mask, unsigned int query_flags) > +{ > + struct inode *const inode = d_inode(path->dentry); > + struct block_device *bdev = inode->i_sb->s_bdev; > + unsigned int blksize = (1 << inode->i_blkbits); > + > + if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) { > + stat->result_mask |= STATX_DIOALIGN; > + > + if (bdev) > + blksize = bdev_logical_block_size(bdev); > + stat->dio_mem_align = blksize; > + stat->dio_offset_align = blksize; > + } > + > + generic_fillattr(idmap, request_mask, inode, stat); > + return 0; > +} > + > int nilfs_permission(struct mnt_idmap *idmap, struct inode *inode, > int mask) > { > diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c > index c950139db6ef..ad56f4f8be1f 100644 > --- a/fs/nilfs2/namei.c > +++ b/fs/nilfs2/namei.c > @@ -546,6 +546,7 @@ const struct inode_operations nilfs_dir_inode_operations = { > .mknod = nilfs_mknod, > .rename = nilfs_rename, > .setattr = nilfs_setattr, > + .getattr = nilfs_getattr, > .permission = nilfs_permission, > .fiemap = nilfs_fiemap, > .fileattr_get = nilfs_fileattr_get, > @@ -554,6 +555,7 @@ const struct inode_operations nilfs_dir_inode_operations = { > > const struct inode_operations nilfs_special_inode_operations = { > .setattr = nilfs_setattr, > + .getattr = nilfs_getattr, > .permission = nilfs_permission, > }; > > diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h > index 4017f7856440..c2182bb660bf 100644 > --- a/fs/nilfs2/nilfs.h > +++ b/fs/nilfs2/nilfs.h > @@ -280,6 +280,8 @@ extern void nilfs_truncate(struct inode *); > extern void nilfs_evict_inode(struct inode *); > extern int nilfs_setattr(struct mnt_idmap *, struct dentry *, > struct iattr *); > +extern int nilfs_getattr(struct mnt_idmap *idmap, const struct path *path, > + struct kstat *stat, u3 request_mask, unsigned int query_flags); > extern void nilfs_write_failed(struct address_space *mapping, loff_t to); > int nilfs_permission(struct mnt_idmap *idmap, struct inode *inode, > int mask);
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 0e3fc5ba33c7..5528918d4b96 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -154,6 +154,7 @@ const struct file_operations nilfs_file_operations = { const struct inode_operations nilfs_file_inode_operations = { .setattr = nilfs_setattr, + .getattr = nilfs_getattr, .permission = nilfs_permission, .fiemap = nilfs_fiemap, .fileattr_get = nilfs_fileattr_get, diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 7340a01d80e1..7bf062793642 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -1001,6 +1001,26 @@ int nilfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, return err; } +int nilfs_getattr(struct mnt_idmap *idmap, const struct path *path, + struct kstat *stat, u3 request_mask, unsigned int query_flags) +{ + struct inode *const inode = d_inode(path->dentry); + struct block_device *bdev = inode->i_sb->s_bdev; + unsigned int blksize = (1 << inode->i_blkbits); + + if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) { + stat->result_mask |= STATX_DIOALIGN; + + if (bdev) + blksize = bdev_logical_block_size(bdev); + stat->dio_mem_align = blksize; + stat->dio_offset_align = blksize; + } + + generic_fillattr(idmap, request_mask, inode, stat); + return 0; +} + int nilfs_permission(struct mnt_idmap *idmap, struct inode *inode, int mask) { diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index c950139db6ef..ad56f4f8be1f 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -546,6 +546,7 @@ const struct inode_operations nilfs_dir_inode_operations = { .mknod = nilfs_mknod, .rename = nilfs_rename, .setattr = nilfs_setattr, + .getattr = nilfs_getattr, .permission = nilfs_permission, .fiemap = nilfs_fiemap, .fileattr_get = nilfs_fileattr_get, @@ -554,6 +555,7 @@ const struct inode_operations nilfs_dir_inode_operations = { const struct inode_operations nilfs_special_inode_operations = { .setattr = nilfs_setattr, + .getattr = nilfs_getattr, .permission = nilfs_permission, }; diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 4017f7856440..c2182bb660bf 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -280,6 +280,8 @@ extern void nilfs_truncate(struct inode *); extern void nilfs_evict_inode(struct inode *); extern int nilfs_setattr(struct mnt_idmap *, struct dentry *, struct iattr *); +extern int nilfs_getattr(struct mnt_idmap *idmap, const struct path *path, + struct kstat *stat, u3 request_mask, unsigned int query_flags); extern void nilfs_write_failed(struct address_space *mapping, loff_t to); int nilfs_permission(struct mnt_idmap *idmap, struct inode *inode, int mask);
Add support for STATX_DIOALIGN to nilfs2, so that direct I/O alignment restrictions are exposed to userspace in a generic way. By default, nilfs2 uses the default getattr implemented at vfs layer, so we should implement getattr in nilfs2 to fill the dio_xx_align members. We have done the following test: [Before] ``` ./statx_test /mnt/nilfs2/testfile statx(/mnt/nilfs2/test) = 0 dio mem align:0 dio offset align:0 ``` [After] ``` ./statx_test /mnt/nilfs2/test statx(/mnt/nilfs2/test) = 0 dio mem align:512 dio offset align:512 ``` Signed-off-by: Hongbo Li <lihongbo22@huawei.com> --- fs/nilfs2/file.c | 1 + fs/nilfs2/inode.c | 20 ++++++++++++++++++++ fs/nilfs2/namei.c | 2 ++ fs/nilfs2/nilfs.h | 2 ++ 4 files changed, 25 insertions(+)