From: Andi Kleen Convert the XFS ioctl handlers over to unlocked_ioctl and compat_ioctl. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/fs/xfs/linux-2.6/xfs_file.c | 25 +++-- 25-akpm/fs/xfs/linux-2.6/xfs_ioctl32.c | 151 ++++++++++++++++----------------- 25-akpm/fs/xfs/linux-2.6/xfs_ioctl32.h | 11 -- 25-akpm/fs/xfs/linux-2.6/xfs_super.c | 8 - 4 files changed, 92 insertions(+), 103 deletions(-) diff -puN fs/xfs/linux-2.6/xfs_file.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl fs/xfs/linux-2.6/xfs_file.c --- 25/fs/xfs/linux-2.6/xfs_file.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl Tue Jan 18 15:32:05 2005 +++ 25-akpm/fs/xfs/linux-2.6/xfs_file.c Tue Jan 18 15:32:05 2005 @@ -51,6 +51,7 @@ #include "xfs_inode.h" #include "xfs_error.h" #include "xfs_rw.h" +#include "xfs_ioctl32.h" #include #include @@ -415,20 +416,18 @@ linvfs_file_mmap( } -STATIC int +STATIC long linvfs_ioctl( - struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int error; + struct inode *inode = filp->f_dentry->d_inode; vnode_t *vp = LINVFS_GET_VP(inode); - unlock_kernel(); VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); VMODIFY(vp); - lock_kernel(); /* NOTE: some of the ioctl's return positive #'s as a * byte count indicating success, such as @@ -439,21 +438,19 @@ linvfs_ioctl( return error; } -STATIC int +STATIC long linvfs_ioctl_invis( - struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int error; + struct inode *inode = filp->f_dentry->d_inode; vnode_t *vp = LINVFS_GET_VP(inode); - unlock_kernel(); ASSERT(vp); VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); VMODIFY(vp); - lock_kernel(); /* NOTE: some of the ioctl's return positive #'s as a * byte count indicating success, such as @@ -495,7 +492,10 @@ struct file_operations linvfs_file_opera .aio_read = linvfs_aio_read, .aio_write = linvfs_aio_write, .sendfile = linvfs_sendfile, - .ioctl = linvfs_ioctl, + .unlocked_ioctl = linvfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = xfs_compat_ioctl, +#endif .mmap = linvfs_file_mmap, .open = linvfs_open, .release = linvfs_release, @@ -511,7 +511,10 @@ struct file_operations linvfs_invis_file .aio_read = linvfs_aio_read_invis, .aio_write = linvfs_aio_write_invis, .sendfile = linvfs_sendfile, - .ioctl = linvfs_ioctl_invis, + .unlocked_ioctl = linvfs_ioctl_invis, +#ifdef CONFIG_COMPAT + .compat_ioctl = xfs_compat_invis_ioctl, +#endif .mmap = linvfs_file_mmap, .open = linvfs_open, .release = linvfs_release, @@ -522,7 +525,7 @@ struct file_operations linvfs_invis_file struct file_operations linvfs_dir_operations = { .read = generic_read_dir, .readdir = linvfs_readdir, - .ioctl = linvfs_ioctl, + .unlocked_ioctl = linvfs_ioctl, .fsync = linvfs_fsync, }; diff -puN fs/xfs/linux-2.6/xfs_ioctl32.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl fs/xfs/linux-2.6/xfs_ioctl32.c --- 25/fs/xfs/linux-2.6/xfs_ioctl32.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl Tue Jan 18 15:32:05 2005 +++ 25-akpm/fs/xfs/linux-2.6/xfs_ioctl32.c Tue Jan 18 15:32:05 2005 @@ -37,10 +37,14 @@ #include #include #include +#include #include +#include "xfs.h" #include "xfs_types.h" #include "xfs_fs.h" +#include "xfs_vfs.h" +#include "xfs_vnode.h" #include "xfs_dfrag.h" #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) @@ -54,12 +58,8 @@ typedef struct xfs_fsop_bulkreq32 { __s32 ocount; /* output count pointer */ } xfs_fsop_bulkreq32_t; -static int -xfs_ioctl32_bulkstat( - unsigned int fd, - unsigned int cmd, - unsigned long arg, - struct file * file) +static unsigned long +xfs_ioctl32_bulkstat(unsigned long arg) { xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); @@ -74,89 +74,90 @@ xfs_ioctl32_bulkstat( put_user(compat_ptr(addr), &p->ocount)) return -EFAULT; - return sys_ioctl(fd, cmd, (unsigned long)p); + return (unsigned long)p; } #endif -struct ioctl_trans xfs_ioctl32_trans[] = { - { XFS_IOC_DIOINFO, }, - { XFS_IOC_FSGEOMETRY_V1, }, - { XFS_IOC_FSGEOMETRY, }, - { XFS_IOC_GETVERSION, }, - { XFS_IOC_GETXFLAGS, }, - { XFS_IOC_SETXFLAGS, }, - { XFS_IOC_FSGETXATTR, }, - { XFS_IOC_FSSETXATTR, }, - { XFS_IOC_FSGETXATTRA, }, - { XFS_IOC_FSSETDM, }, - { XFS_IOC_GETBMAP, }, - { XFS_IOC_GETBMAPA, }, - { XFS_IOC_GETBMAPX, }, +static long +__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) +{ + int error; + struct inode *inode = f->f_dentry->d_inode; + vnode_t *vp = LINVFS_GET_VP(inode); + + switch (cmd) { + case XFS_IOC_DIOINFO: + case XFS_IOC_FSGEOMETRY_V1: + case XFS_IOC_FSGEOMETRY: + case XFS_IOC_GETVERSION: + case XFS_IOC_GETXFLAGS: + case XFS_IOC_SETXFLAGS: + case XFS_IOC_FSGETXATTR: + case XFS_IOC_FSSETXATTR: + case XFS_IOC_FSGETXATTRA: + case XFS_IOC_FSSETDM: + case XFS_IOC_GETBMAP: + case XFS_IOC_GETBMAPA: + case XFS_IOC_GETBMAPX: /* not handled - { XFS_IOC_FD_TO_HANDLE, }, - { XFS_IOC_PATH_TO_HANDLE, }, - { XFS_IOC_PATH_TO_HANDLE, }, - { XFS_IOC_PATH_TO_FSHANDLE, }, - { XFS_IOC_OPEN_BY_HANDLE, }, - { XFS_IOC_FSSETDM_BY_HANDLE, }, - { XFS_IOC_READLINK_BY_HANDLE, }, - { XFS_IOC_ATTRLIST_BY_HANDLE, }, - { XFS_IOC_ATTRMULTI_BY_HANDLE, }, + case XFS_IOC_FD_TO_HANDLE: + case XFS_IOC_PATH_TO_HANDLE: + case XFS_IOC_PATH_TO_HANDLE: + case XFS_IOC_PATH_TO_FSHANDLE: + case XFS_IOC_OPEN_BY_HANDLE: + case XFS_IOC_FSSETDM_BY_HANDLE: + case XFS_IOC_READLINK_BY_HANDLE: + case XFS_IOC_ATTRLIST_BY_HANDLE: + case XFS_IOC_ATTRMULTI_BY_HANDLE: */ - { XFS_IOC_FSCOUNTS, NULL, }, - { XFS_IOC_SET_RESBLKS, NULL, }, - { XFS_IOC_GET_RESBLKS, NULL, }, - { XFS_IOC_FSGROWFSDATA, NULL, }, - { XFS_IOC_FSGROWFSLOG, NULL, }, - { XFS_IOC_FSGROWFSRT, NULL, }, - { XFS_IOC_FREEZE, NULL, }, - { XFS_IOC_THAW, NULL, }, - { XFS_IOC_GOINGDOWN, NULL, }, - { XFS_IOC_ERROR_INJECTION, NULL, }, - { XFS_IOC_ERROR_CLEARALL, NULL, }, + case XFS_IOC_FSCOUNTS: + case XFS_IOC_SET_RESBLKS: + case XFS_IOC_GET_RESBLKS: + case XFS_IOC_FSGROWFSDATA: + case XFS_IOC_FSGROWFSLOG: + case XFS_IOC_FSGROWFSRT: + case XFS_IOC_FREEZE: + case XFS_IOC_THAW: + case XFS_IOC_GOINGDOWN: + case XFS_IOC_ERROR_INJECTION: + case XFS_IOC_ERROR_CLEARALL: + break; + #ifndef BROKEN_X86_ALIGNMENT /* xfs_flock_t and xfs_bstat_t have wrong u32 vs u64 alignment */ - { XFS_IOC_ALLOCSP, }, - { XFS_IOC_FREESP, }, - { XFS_IOC_RESVSP, }, - { XFS_IOC_UNRESVSP, }, - { XFS_IOC_ALLOCSP64, }, - { XFS_IOC_FREESP64, }, - { XFS_IOC_RESVSP64, }, - { XFS_IOC_UNRESVSP64, }, - { XFS_IOC_SWAPEXT, }, - { XFS_IOC_FSBULKSTAT_SINGLE, xfs_ioctl32_bulkstat }, - { XFS_IOC_FSBULKSTAT, xfs_ioctl32_bulkstat}, - { XFS_IOC_FSINUMBERS, xfs_ioctl32_bulkstat}, + case XFS_IOC_ALLOCSP: + case XFS_IOC_FREESP: + case XFS_IOC_RESVSP: + case XFS_IOC_UNRESVSP: + case XFS_IOC_ALLOCSP64: + case XFS_IOC_FREESP64: + case XFS_IOC_RESVSP64: + case XFS_IOC_UNRESVSP64: + case XFS_IOC_SWAPEXT: + break; + + case XFS_IOC_FSBULKSTAT_SINGLE: + case XFS_IOC_FSBULKSTAT: + case XFS_IOC_FSINUMBERS: + arg = xfs_ioctl32_bulkstat(arg); + break; #endif - { 0, }, -}; - -int __init -xfs_ioctl32_init(void) -{ - int error, i; - - for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++) { - error = register_ioctl32_conversion(xfs_ioctl32_trans[i].cmd, - xfs_ioctl32_trans[i].handler); - if (error) - goto fail; + default: + return -ENOIOCTLCMD; } - return 0; + VOP_IOCTL(vp, inode, f, mode, cmd, (void __user *)arg, error); + VMODIFY(vp); - fail: - while (--i) - unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd); return error; } -void -xfs_ioctl32_exit(void) +long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) { - int i; + return __xfs_compat_ioctl(0, f, cmd, arg); +} - for (i = 0; xfs_ioctl32_trans[i].cmd != 0; i++) - unregister_ioctl32_conversion(xfs_ioctl32_trans[i].cmd); +long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg) +{ + return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg); } diff -puN fs/xfs/linux-2.6/xfs_ioctl32.h~convert-xfs-to-unlocked_ioctl-and-compat_ioctl fs/xfs/linux-2.6/xfs_ioctl32.h --- 25/fs/xfs/linux-2.6/xfs_ioctl32.h~convert-xfs-to-unlocked_ioctl-and-compat_ioctl Tue Jan 18 15:32:05 2005 +++ 25-akpm/fs/xfs/linux-2.6/xfs_ioctl32.h Tue Jan 18 15:32:05 2005 @@ -30,12 +30,5 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include - -#ifdef CONFIG_COMPAT -extern int xfs_ioctl32_init(void); -extern void xfs_ioctl32_exit(void); -#else -static inline int xfs_ioctl32_init(void) { return 0; } -static inline void xfs_ioctl32_exit(void) { } -#endif +long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); diff -puN fs/xfs/linux-2.6/xfs_super.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl fs/xfs/linux-2.6/xfs_super.c --- 25/fs/xfs/linux-2.6/xfs_super.c~convert-xfs-to-unlocked_ioctl-and-compat_ioctl Tue Jan 18 15:32:05 2005 +++ 25-akpm/fs/xfs/linux-2.6/xfs_super.c Tue Jan 18 15:32:05 2005 @@ -885,10 +885,6 @@ init_xfs_fs( void ) goto undo_shaker; } - error = xfs_ioctl32_init(); - if (error) - goto undo_ioctl32; - error = register_filesystem(&xfs_fs_type); if (error) goto undo_register; @@ -896,9 +892,6 @@ init_xfs_fs( void ) return 0; undo_register: - xfs_ioctl32_exit(); - -undo_ioctl32: kmem_shake_deregister(xfs_inode_shaker); undo_shaker: @@ -917,7 +910,6 @@ exit_xfs_fs( void ) vfs_exitquota(); XFS_DM_EXIT(&xfs_fs_type); unregister_filesystem(&xfs_fs_type); - xfs_ioctl32_exit(); kmem_shake_deregister(xfs_inode_shaker); xfs_cleanup(); pagebuf_terminate(); _