Loading fs/xfs/linux-2.6/xfs_ioctl.c +3 −3 Original line number Diff line number Diff line Loading @@ -490,7 +490,7 @@ xfs_attrlist_by_handle( return -error; } STATIC int int xfs_attrmulti_attr_get( struct inode *inode, char *name, Loading Loading @@ -519,7 +519,7 @@ xfs_attrmulti_attr_get( return error; } STATIC int int xfs_attrmulti_attr_set( struct inode *inode, char *name, Loading Loading @@ -549,7 +549,7 @@ xfs_attrmulti_attr_set( return error; } STATIC int int xfs_attrmulti_attr_remove( struct inode *inode, char *name, Loading fs/xfs/linux-2.6/xfs_ioctl.h +23 −0 Original line number Diff line number Diff line Loading @@ -44,4 +44,27 @@ xfs_readlink_by_handle( xfs_mount_t *mp, xfs_fsop_handlereq_t *hreq, struct inode *parinode); extern int xfs_attrmulti_attr_get( struct inode *inode, char *name, char __user *ubuf, __uint32_t *len, __uint32_t flags); extern int xfs_attrmulti_attr_set( struct inode *inode, char *name, const char __user *ubuf, __uint32_t len, __uint32_t flags); extern int xfs_attrmulti_attr_remove( struct inode *inode, char *name, __uint32_t flags); #endif fs/xfs/linux-2.6/xfs_ioctl32.c +90 −4 Original line number Diff line number Diff line Loading @@ -476,6 +476,93 @@ xfs_compat_attrlist_by_handle( return -error; } STATIC int xfs_compat_attrmulti_by_handle( xfs_mount_t *mp, void __user *arg, struct inode *parinode) { int error; compat_xfs_attr_multiop_t *ops; compat_xfs_fsop_attrmulti_handlereq_t am_hreq; struct inode *inode; unsigned int i, size; char *attr_name; if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); if (copy_from_user(&am_hreq, arg, sizeof(compat_xfs_fsop_attrmulti_handlereq_t))) return -XFS_ERROR(EFAULT); error = xfs_vget_fsop_handlereq_compat(mp, parinode, &am_hreq.hreq, &inode); if (error) goto out; error = E2BIG; size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t); if (!size || size > 16 * PAGE_SIZE) goto out_vn_rele; error = ENOMEM; ops = kmalloc(size, GFP_KERNEL); if (!ops) goto out_vn_rele; error = EFAULT; if (copy_from_user(ops, compat_ptr(am_hreq.ops), size)) goto out_kfree_ops; attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); if (!attr_name) goto out_kfree_ops; error = 0; for (i = 0; i < am_hreq.opcount; i++) { ops[i].am_error = strncpy_from_user(attr_name, compat_ptr(ops[i].am_attrname), MAXNAMELEN); if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) error = -ERANGE; if (ops[i].am_error < 0) break; switch (ops[i].am_opcode) { case ATTR_OP_GET: ops[i].am_error = xfs_attrmulti_attr_get(inode, attr_name, compat_ptr(ops[i].am_attrvalue), &ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_SET: ops[i].am_error = xfs_attrmulti_attr_set(inode, attr_name, compat_ptr(ops[i].am_attrvalue), ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_REMOVE: ops[i].am_error = xfs_attrmulti_attr_remove(inode, attr_name, ops[i].am_flags); break; default: ops[i].am_error = EINVAL; } } if (copy_to_user(compat_ptr(am_hreq.ops), ops, size)) error = XFS_ERROR(EFAULT); kfree(attr_name); out_kfree_ops: kfree(ops); out_vn_rele: iput(inode); out: return -error; } STATIC long xfs_compat_ioctl( xfs_inode_t *ip, Loading @@ -499,10 +586,7 @@ xfs_compat_ioctl( case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAPA: case XFS_IOC_GETBMAPX: /* not handled case XFS_IOC_FSSETDM_BY_HANDLE: case XFS_IOC_ATTRMULTI_BY_HANDLE: */ /* case XFS_IOC_FSSETDM_BY_HANDLE: not handled */ case XFS_IOC_FSCOUNTS: case XFS_IOC_SET_RESBLKS: case XFS_IOC_GET_RESBLKS: Loading Loading @@ -610,6 +694,8 @@ xfs_compat_ioctl( } case XFS_IOC_ATTRLIST_BY_HANDLE_32: return xfs_compat_attrlist_by_handle(mp, arg, inode); case XFS_IOC_ATTRMULTI_BY_HANDLE_32: return xfs_compat_attrmulti_by_handle(mp, arg, inode); default: return -XFS_ERROR(ENOIOCTLCMD); } Loading fs/xfs/linux-2.6/xfs_ioctl32.h +20 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,26 @@ typedef struct compat_xfs_fsop_attrlist_handlereq { #define XFS_IOC_ATTRLIST_BY_HANDLE_32 \ _IOW('X', 122, struct compat_xfs_fsop_attrlist_handlereq) /* am_opcodes defined in xfs_fs.h */ typedef struct compat_xfs_attr_multiop { __u32 am_opcode; __s32 am_error; compat_uptr_t am_attrname; compat_uptr_t am_attrvalue; __u32 am_length; __u32 am_flags; } compat_xfs_attr_multiop_t; typedef struct compat_xfs_fsop_attrmulti_handlereq { struct compat_xfs_fsop_handlereq hreq; /* handle interface structure */ __u32 opcount;/* count of following multiop */ /* ptr to compat_xfs_attr_multiop */ compat_uptr_t ops; /* attr_multi data */ } compat_xfs_fsop_attrmulti_handlereq_t; #define XFS_IOC_ATTRMULTI_BY_HANDLE_32 \ _IOW('X', 123, struct compat_xfs_fsop_attrmulti_handlereq) #ifdef BROKEN_X86_ALIGNMENT /* on ia32 l_start is on a 32-bit boundary */ typedef struct compat_xfs_flock64 { Loading Loading
fs/xfs/linux-2.6/xfs_ioctl.c +3 −3 Original line number Diff line number Diff line Loading @@ -490,7 +490,7 @@ xfs_attrlist_by_handle( return -error; } STATIC int int xfs_attrmulti_attr_get( struct inode *inode, char *name, Loading Loading @@ -519,7 +519,7 @@ xfs_attrmulti_attr_get( return error; } STATIC int int xfs_attrmulti_attr_set( struct inode *inode, char *name, Loading Loading @@ -549,7 +549,7 @@ xfs_attrmulti_attr_set( return error; } STATIC int int xfs_attrmulti_attr_remove( struct inode *inode, char *name, Loading
fs/xfs/linux-2.6/xfs_ioctl.h +23 −0 Original line number Diff line number Diff line Loading @@ -44,4 +44,27 @@ xfs_readlink_by_handle( xfs_mount_t *mp, xfs_fsop_handlereq_t *hreq, struct inode *parinode); extern int xfs_attrmulti_attr_get( struct inode *inode, char *name, char __user *ubuf, __uint32_t *len, __uint32_t flags); extern int xfs_attrmulti_attr_set( struct inode *inode, char *name, const char __user *ubuf, __uint32_t len, __uint32_t flags); extern int xfs_attrmulti_attr_remove( struct inode *inode, char *name, __uint32_t flags); #endif
fs/xfs/linux-2.6/xfs_ioctl32.c +90 −4 Original line number Diff line number Diff line Loading @@ -476,6 +476,93 @@ xfs_compat_attrlist_by_handle( return -error; } STATIC int xfs_compat_attrmulti_by_handle( xfs_mount_t *mp, void __user *arg, struct inode *parinode) { int error; compat_xfs_attr_multiop_t *ops; compat_xfs_fsop_attrmulti_handlereq_t am_hreq; struct inode *inode; unsigned int i, size; char *attr_name; if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); if (copy_from_user(&am_hreq, arg, sizeof(compat_xfs_fsop_attrmulti_handlereq_t))) return -XFS_ERROR(EFAULT); error = xfs_vget_fsop_handlereq_compat(mp, parinode, &am_hreq.hreq, &inode); if (error) goto out; error = E2BIG; size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t); if (!size || size > 16 * PAGE_SIZE) goto out_vn_rele; error = ENOMEM; ops = kmalloc(size, GFP_KERNEL); if (!ops) goto out_vn_rele; error = EFAULT; if (copy_from_user(ops, compat_ptr(am_hreq.ops), size)) goto out_kfree_ops; attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); if (!attr_name) goto out_kfree_ops; error = 0; for (i = 0; i < am_hreq.opcount; i++) { ops[i].am_error = strncpy_from_user(attr_name, compat_ptr(ops[i].am_attrname), MAXNAMELEN); if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) error = -ERANGE; if (ops[i].am_error < 0) break; switch (ops[i].am_opcode) { case ATTR_OP_GET: ops[i].am_error = xfs_attrmulti_attr_get(inode, attr_name, compat_ptr(ops[i].am_attrvalue), &ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_SET: ops[i].am_error = xfs_attrmulti_attr_set(inode, attr_name, compat_ptr(ops[i].am_attrvalue), ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_REMOVE: ops[i].am_error = xfs_attrmulti_attr_remove(inode, attr_name, ops[i].am_flags); break; default: ops[i].am_error = EINVAL; } } if (copy_to_user(compat_ptr(am_hreq.ops), ops, size)) error = XFS_ERROR(EFAULT); kfree(attr_name); out_kfree_ops: kfree(ops); out_vn_rele: iput(inode); out: return -error; } STATIC long xfs_compat_ioctl( xfs_inode_t *ip, Loading @@ -499,10 +586,7 @@ xfs_compat_ioctl( case XFS_IOC_GETBMAP: case XFS_IOC_GETBMAPA: case XFS_IOC_GETBMAPX: /* not handled case XFS_IOC_FSSETDM_BY_HANDLE: case XFS_IOC_ATTRMULTI_BY_HANDLE: */ /* case XFS_IOC_FSSETDM_BY_HANDLE: not handled */ case XFS_IOC_FSCOUNTS: case XFS_IOC_SET_RESBLKS: case XFS_IOC_GET_RESBLKS: Loading Loading @@ -610,6 +694,8 @@ xfs_compat_ioctl( } case XFS_IOC_ATTRLIST_BY_HANDLE_32: return xfs_compat_attrlist_by_handle(mp, arg, inode); case XFS_IOC_ATTRMULTI_BY_HANDLE_32: return xfs_compat_attrmulti_by_handle(mp, arg, inode); default: return -XFS_ERROR(ENOIOCTLCMD); } Loading
fs/xfs/linux-2.6/xfs_ioctl32.h +20 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,26 @@ typedef struct compat_xfs_fsop_attrlist_handlereq { #define XFS_IOC_ATTRLIST_BY_HANDLE_32 \ _IOW('X', 122, struct compat_xfs_fsop_attrlist_handlereq) /* am_opcodes defined in xfs_fs.h */ typedef struct compat_xfs_attr_multiop { __u32 am_opcode; __s32 am_error; compat_uptr_t am_attrname; compat_uptr_t am_attrvalue; __u32 am_length; __u32 am_flags; } compat_xfs_attr_multiop_t; typedef struct compat_xfs_fsop_attrmulti_handlereq { struct compat_xfs_fsop_handlereq hreq; /* handle interface structure */ __u32 opcount;/* count of following multiop */ /* ptr to compat_xfs_attr_multiop */ compat_uptr_t ops; /* attr_multi data */ } compat_xfs_fsop_attrmulti_handlereq_t; #define XFS_IOC_ATTRMULTI_BY_HANDLE_32 \ _IOW('X', 123, struct compat_xfs_fsop_attrmulti_handlereq) #ifdef BROKEN_X86_ALIGNMENT /* on ia32 l_start is on a 32-bit boundary */ typedef struct compat_xfs_flock64 { Loading