fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
Subsystems (3)
PATCH v2 1/1 fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
This patch adds ioctls to vfs for compatibility with legacy XFS pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation effectively invokes sys_fallocate for the new ioctls.
Note: These legacy ioctls are also implemented by OCFS2.
Changes in v2:
- Dropped the incorrect handling of *UNRESVSP* ioctl.
- Made the ioctl and argument structure kernel only (__KERNEL__)
--- fs/ioctl.c | 35 ++++++++++++++++++++++++++ fs/open.c | 51 ++++++++++++++++++------------------- include/linux/falloc.h | 21 +++++++++++++++ include/linux/fs.h | 2 + 4 files changed, 83 insertions(+), 26 deletions(-)
fs/ioctl.c +35 -0
@@ -15,6 +15,7 @@#include <linux/uaccess.h> #include <linux/writeback.h> #include <linux/buffer_head.h> +#include <linux/falloc.h> #include <asm/ioctls.h>
@@ -346,6 +347,37 @@ EXPORT_SYMBOL(generic_block_fiemap);#endif /* CONFIG_BLOCK */ +/* +* This provides compatibility with legacy XFS pre-allocation ioctls +* which predate the fallocate syscall. +* +* Only the l_start, l_len and l_whence fields of the 'struct space_resv' +* are used here, rest are ignored. +*/ +static int ioctl_preallocate (struct file *filp,unsigned long arg) +{ +struct inode *inode = filp->f_path.dentry->d_inode; +struct space_resv sr; + +if (copy_from_user (&sr, (struct space_resv __user *) arg,sizeof (sr))) +return -EFAULT ; + +switch (sr.l_whence) { +case SEEK_SET : +break ; +case SEEK_CUR : + sr.l_start += filp->f_pos; +break ; +case SEEK_END : + sr.l_start +=i_size_read (inode); +break ; +default : +return -EINVAL ; + } + +return do_fallocate (filp,FALLOC_FL_KEEP_SIZE , sr.l_start, sr.l_len); +} +static int file_ioctl (struct file *filp,unsigned int cmd,unsigned long arg) {
@@ -361,6 +393,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,return put_user (inode->i_sb->s_blocksize, p);case FIONREAD :return put_user (i_size_read (inode) - filp->f_pos, p); +case F_IOC_RESVSP : +case F_IOC_RESVSP64 : +return ioctl_preallocate (filp, arg); }return vfs_ioctl (filp, cmd, arg);
fs/open.c +25 -26
87 lines not on this page · raw message
include/linux/falloc.h +21 -0
@@ -3,4 +3,25 @@#define FALLOC_FL_KEEP_SIZE 0x01/* default is extend size */ +#ifdef __KERNEL__ + +/* +* Space reservation ioctls and argument structure +* are designed to be compatible with the legacy XFS ioctls. +*/ +struct space_resv { +__s16 l_type; +__s16 l_whence; +__s64 l_start; +__s64 l_len;/* len == 0 means until end of file */ +__s32 l_sysid; +__u32 l_pid; +__s32 l_pad[4 ];/* reserve area */ +}; + +#define F_IOC_RESVSP _IOW('X', 40, struct space_resv) +#define F_IOC_RESVSP64 _IOW('X', 42, struct space_resv) + +#endif +#endif /* _FALLOC_H_ */
include/linux/fs.h +2 -0
@@ -1671,6 +1671,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode)extern int do_truncate (struct dentry *,loff_t start,unsigned int time_attrs,struct file *filp); +extern long do_fallocate (struct file *file,int mode,loff_t offset, +loff_t len);extern long do_sys_open (int dfd,const char __user *filename,int flags,int mode);extern struct file *filp_open (const char *,int ,int );
Quoted 10 lines · Ankit Jain
This patch adds ioctls to vfs for compatibility with legacy XFS pre-allocation ioctls (XFS_IOC_*RESVP*). The implementation effectively invokes
sys_fallocatefor the new ioctls.
Note: These legacy ioctls are also implemented by OCFS2.Changes in v2:
- Dropped the incorrect handling of *UNRESVSP* ioctl.
- Made the ioctl and argument structure kernel only (__KERNEL__)Signed-off-by Ankit Jain <[email protected]>
.....
fs/ioctl.c static int file_ioctl(struct file *filp, unsigned int cmd, · line 401
Quoted 10 lines
fs/ioctl.c +3
-0@@ -361,6 +393,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,return put_user (inode->i_sb->s_blocksize, p);case FIONREAD :return put_user (i_size_read (inode) - filp->f_pos, p); +case F_IOC_RESVSP : +case F_IOC_RESVSP64 : +return ioctl_preallocate (filp, arg); }return vfs_ioctl (filp, cmd, arg);
Adding this here breaks XFS_IOC_RESVSP in subtle and interesting ways.
XFS_IOC_RESVSP supports invisible I/O, and that means XFS_IOC_RESVSP needs to be passed through to vfs_ioctl() to vector to XFS to handle.
This happenѕ because:
include/linux/falloc.h line 23
Quoted 12 lines
include/linux/falloc.h +12
-0+struct space_resv { +__s16 l_type; +__s16 l_whence; +__s64 l_start; +__s64 l_len;/* len == 0 means until end of file */ +__s32 l_sysid; +__u32 l_pid; +__s32 l_pad[4 ];/* reserve area */ +}; + +#define F_IOC_RESVSP _IOW('X', 40, struct space_resv) +#define F_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
Is the same as:
#define XFS_IOC_RESVSP _IOW ('X', 40, struct xfs_flock64)
#define XFS_IOC_RESVSP64 _IOW ('X', 42, struct xfs_flock64)
because:
typedef struct xfs_flock64 {
__s16 l_type;
__s16 l_whence;
__s64 l_start;
__s64 l_len; /* len == 0 means until end of file */
__s32 l_sysid;
__u32 l_pid;
__s32 l_pad[4]; /* reserve area */
} xfs_flock64_t;is the same size as struct space_resv. Hence existing calls to XFS_IOC_RESVSP will now vector incorrectly down the fallocate path resulting in invisible operations will now be visible....
Cheers,
Dave.
Signature · 6 lines
Dave Chinner [email protected] -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 3 lines · Dave Chinner
XFS_IOC_RESVSPsupports invisible I/O, and that meansXFS_IOC_RESVSPneeds to be passed through tovfs_ioctl()to vector to XFS to handle.
When the current XFS git tree gets merged to mainline before this patch. invisible I/O handling is now FMODE_NOCMTIME in file->f_flags which this patch will pass through to the filesystem. We just need to chage xfs_vn_fallocate ot honour it.