]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/linux-2.6/xfs_ioctl.c
[PATCH] r/o bind mounts: elevate write count for ioctls()
[linux-2.6-omap-h63xx.git] / fs / xfs / linux-2.6 / xfs_ioctl.c
index bf77597938564d1b498c10e90440ff3339495684..4ddb86b73c6b537034b09d2632c7d2061432a736 100644 (file)
@@ -535,8 +535,6 @@ xfs_attrmulti_attr_set(
        char                    *kbuf;
        int                     error = EFAULT;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return EPERM;
        if (len > XATTR_SIZE_MAX)
@@ -562,8 +560,6 @@ xfs_attrmulti_attr_remove(
        char                    *name,
        __uint32_t              flags)
 {
-       if (IS_RDONLY(inode))
-               return -EROFS;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return EPERM;
        return xfs_attr_remove(XFS_I(inode), name, flags);
@@ -573,6 +569,7 @@ STATIC int
 xfs_attrmulti_by_handle(
        xfs_mount_t             *mp,
        void                    __user *arg,
+       struct file             *parfilp,
        struct inode            *parinode)
 {
        int                     error;
@@ -626,13 +623,21 @@ xfs_attrmulti_by_handle(
                                        &ops[i].am_length, ops[i].am_flags);
                        break;
                case ATTR_OP_SET:
+                       ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
+                       if (ops[i].am_error)
+                               break;
                        ops[i].am_error = xfs_attrmulti_attr_set(inode,
                                        attr_name, ops[i].am_attrvalue,
                                        ops[i].am_length, ops[i].am_flags);
+                       mnt_drop_write(parfilp->f_path.mnt);
                        break;
                case ATTR_OP_REMOVE:
+                       ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
+                       if (ops[i].am_error)
+                               break;
                        ops[i].am_error = xfs_attrmulti_attr_remove(inode,
                                        attr_name, ops[i].am_flags);
+                       mnt_drop_write(parfilp->f_path.mnt);
                        break;
                default:
                        ops[i].am_error = EINVAL;
@@ -1133,7 +1138,7 @@ xfs_ioctl(
                return xfs_attrlist_by_handle(mp, arg, inode);
 
        case XFS_IOC_ATTRMULTI_BY_HANDLE:
-               return xfs_attrmulti_by_handle(mp, arg, inode);
+               return xfs_attrmulti_by_handle(mp, arg, filp, inode);
 
        case XFS_IOC_SWAPEXT: {
                error = xfs_swapext((struct xfs_swapext __user *)arg);