Re: [PATCH v2 3/5]add metadata_readahead ioctl in vfs
From: Shaohua Li <hidden>
Date: 2011-01-05 02:11:36
On Tue, 2011-01-04 at 17:51 +0800, Arnd Bergmann wrote:
On Tuesday 04 January 2011 06:40:37 Shaohua Li wrote:quoted
/* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too.@@ -664,6 +682,9 @@ int do_vfs_ioctl(struct file *filp, unsi case FIMETADATA_INCORE: return ioctl_metadata_incore(filp, argp); + case FIMETADATA_READAHEAD: + return ioctl_metadata_readahead(filp, argp); + default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg);Did you notice the comment above the function? ;-) You should really add the new ioctls to compat_sys_ioctl, not to the COMPATIBLE_IOCTL() list, in order to make the behavior consistent between 32 and 64 bit user space. The main difference is that all ioctl commands that are hardcoded in the functions get called before trying to call the file system specific .ioctl method.quoted
+struct metadata_readahead_args { + __u64 offset; + __u64 size; +}; + #define NR_FILE 8192 /* this can well be larger on a larger system */ #define MAY_EXEC 1@@ -338,6 +343,7 @@ struct metadata_incore_args { #define FITHAW _IOWR('X', 120, int) /* Thaw */ #define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */ #define FIMETADATA_INCORE _IOWR('X', 122, struct metadata_incore_args) +#define FIMETADATA_READAHEAD _IOR('X', 123, struct metadata_readahead_args)This should be _IOW, not _IOR. Otherwise looks good.
Thanks, fixed them. Subject: add metadata_readahead ioctl in vfs Add metadata readahead ioctl in vfs. Filesystem can hook to super_operations.metadata_readahead to handle filesystem specific task. Next patch will give an example how btrfs implements it. Signed-off-by: Shaohua Li <redacted> --- fs/compat_ioctl.c | 2 ++ fs/ioctl.c | 21 +++++++++++++++++++++ include/linux/fs.h | 8 ++++++++ 3 files changed, 31 insertions(+) Index: linux/fs/ioctl.c ===================================================================
--- linux.orig/fs/ioctl.c 2011-01-05 10:00:17.000000000 +0800
+++ linux/fs/ioctl.c 2011-01-05 10:00:42.000000000 +0800@@ -603,6 +603,24 @@ static int ioctl_metadata_incore(struct return entries; } +static int ioctl_metadata_readahead(struct file *filp, void __user *argp) +{ + struct super_block *sb = filp->f_path.dentry->d_inode->i_sb; + struct metadata_readahead_args args; + + if (!sb->s_op->metadata_readahead) + return -EINVAL; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + + /* readahead in page unit */ + if ((args.offset & ~PAGE_CACHE_MASK) || (args.size & ~PAGE_CACHE_MASK)) + return -EINVAL; + + return sb->s_op->metadata_readahead(sb, args.offset, args.size); +} + /* * When you add any new common ioctls to the switches above and below * please update compat_sys_ioctl() too.
@@ -666,6 +684,9 @@ int do_vfs_ioctl(struct file *filp, unsi case FIMETADATA_INCORE: return ioctl_metadata_incore(filp, argp); + case FIMETADATA_READAHEAD: + return ioctl_metadata_readahead(filp, argp); + default: if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) error = file_ioctl(filp, cmd, arg);
Index: linux/include/linux/fs.h ===================================================================
--- linux.orig/include/linux/fs.h 2011-01-05 09:10:12.000000000 +0800
+++ linux/include/linux/fs.h 2011-01-05 10:00:42.000000000 +0800@@ -65,6 +65,11 @@ struct metadata_incore_args { __u32 unused; }; +struct metadata_readahead_args { + __u64 offset; + __u64 size; +}; + #define NR_FILE 8192 /* this can well be larger on a larger system */ #define MAY_EXEC 1
@@ -338,6 +343,7 @@ struct metadata_incore_args { #define FITHAW _IOWR('X', 120, int) /* Thaw */ #define FITRIM _IOWR('X', 121, struct fstrim_range) /* Trim */ #define FIMETADATA_INCORE _IOWR('X', 122, struct metadata_incore_args) +#define FIMETADATA_READAHEAD _IOW('X', 123, struct metadata_readahead_args) #define FS_IOC_GETFLAGS _IOR('f', 1, long) #define FS_IOC_SETFLAGS _IOW('f', 2, long)
@@ -1628,6 +1634,8 @@ struct super_operations { int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); int (*metadata_incore)(struct super_block*, loff_t *offset, ssize_t *size); + int (*metadata_readahead)(struct super_block*, loff_t offset, + ssize_t size); }; /*
Index: linux/fs/compat_ioctl.c ===================================================================
--- linux.orig/fs/compat_ioctl.c 2011-01-05 08:58:06.000000000 +0800
+++ linux/fs/compat_ioctl.c 2011-01-05 10:00:42.000000000 +0800@@ -883,6 +883,7 @@ COMPATIBLE_IOCTL(FIGETBSZ) COMPATIBLE_IOCTL(FIFREEZE) COMPATIBLE_IOCTL(FITHAW) COMPATIBLE_IOCTL(FIMETADATA_INCORE) +COMPATIBLE_IOCTL(FIMETADATA_READAHEAD) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) COMPATIBLE_IOCTL(KDGKBTYPE)
@@ -1579,6 +1580,7 @@ asmlinkage long compat_sys_ioctl(unsigne case FIOASYNC: case FIOQSIZE: case FIMETADATA_INCORE: + case FIMETADATA_READAHEAD: break; #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)