get rid of ioctls, use vserver syscall interface
authorDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Thu, 12 Jul 2007 18:13:44 +0000 (18:13 +0000)
committerDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Thu, 12 Jul 2007 18:13:44 +0000 (18:13 +0000)
fs/ioctl.c
include/linux/vserver/inode.h
include/linux/vserver/inode_cmd.h
kernel/vserver/inode.c
kernel/vserver/switch.c

index b1c6cab..992cdb7 100644 (file)
@@ -197,21 +197,6 @@ int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned lon
                                error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
                        break;
 #endif
-               /*
-                * These cmds needed for PLK - don't lose them!
-                */
-                case FIOC_SETIATTR:
-                case FIOC_GETIATTR:
-                        /*
-                         * Verify that this filp is a file object,
-                         * not (say) a socket.
-                         */
-                        error = -ENOTTY;
-                        if (S_ISREG(filp->f_dentry->d_inode->i_mode) ||
-                            S_ISDIR(filp->f_dentry->d_inode->i_mode))
-                                error = vc_iattr_ioctl(filp->f_dentry,
-                                                       cmd, arg);
-                        break;
 
                default:
                        if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
index 2b35476..333e2f5 100644 (file)
@@ -37,9 +37,6 @@ extern int vc_iattr_ioctl(struct dentry *de,
 #define FIOC_GETXFLG   _IOR('x', 5, long)
 #define FIOC_SETXFLG   _IOW('x', 6, long)
 
-#define FIOC_GETIATTR   _IOR('x', 7, long)
-#define FIOC_SETIATTR   _IOR('x', 8, long)
-
 #else  /* _VX_INODE_H */
 #warning duplicate inclusion
 #endif /* _VX_INODE_H */
index 2fb3ad1..1a6d826 100644 (file)
@@ -10,6 +10,9 @@
 #define VCMD_get_iattr         VC_CMD(INODE, 1, 1)
 #define VCMD_set_iattr         VC_CMD(INODE, 2, 1)
 
+#define VCMD_fget_iattr                VC_CMD(INODE, 3, 0)
+#define VCMD_fset_iattr                VC_CMD(INODE, 4, 0)
+
 struct vcmd_ctx_iattr_v0 {
        /* device handle in id */
        uint64_t ino;
@@ -25,6 +28,12 @@ struct       vcmd_ctx_iattr_v1 {
        uint32_t mask;
 };
 
+struct vcmd_ctx_fiattr_v0 {
+       uint32_t xid;
+       uint32_t flags;
+       uint32_t mask;
+};
+
 
 #ifdef __KERNEL__
 
@@ -50,6 +59,9 @@ extern int vc_set_iattr_v0(uint32_t, void __user *);
 extern int vc_get_iattr(uint32_t, void __user *);
 extern int vc_set_iattr(uint32_t, void __user *);
 
+extern int vc_fget_iattr(uint32_t, void __user *);
+extern int vc_fset_iattr(uint32_t, void __user *);
+
 #ifdef CONFIG_COMPAT
 
 extern int vc_get_iattr_x32(uint32_t, void __user *);
index 2cffdf1..23a59a8 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/parser.h>
+#include <linux/file.h>
 #include <linux/compat.h>
 #include <linux/vserver/inode.h>
 #include <linux/vserver/inode_cmd.h>
@@ -123,6 +124,30 @@ int vc_get_iattr_x32(uint32_t id, void __user *data)
 #endif /* CONFIG_COMPAT */
 
 
+int vc_fget_iattr(uint32_t fd, void __user *data)
+{
+       struct file *filp;
+       struct vcmd_ctx_fiattr_v0 vc_data = { .xid = -1 };
+       int ret;
+
+       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
+               return -EFAULT;
+
+       filp = fget(fd);
+       if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
+               return -EBADF;
+
+       ret = __vc_get_iattr(filp->f_dentry->d_inode,
+               &vc_data.xid, &vc_data.flags, &vc_data.mask);
+
+       fput(filp);
+
+       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
+               ret = -EFAULT;
+       return ret;
+}
+
+
 static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
 {
        struct inode *in = de->d_inode;
@@ -249,35 +274,28 @@ int vc_set_iattr_x32(uint32_t id, void __user *data)
 
 #endif /* CONFIG_COMPAT */
 
-/* required by PLK */
-int vc_iattr_ioctl(struct dentry *de, unsigned int cmd, unsigned long arg)
+int vc_fset_iattr(uint32_t fd, void __user *data)
 {
-       void __user *data = (void __user *)arg;
-       struct vcmd_ctx_iattr_v1 vc_data;
+       struct file *filp;
+       struct vcmd_ctx_fiattr_v0 vc_data;
        int ret;
 
-       /*
-        * I don't think we need any dget/dput pairs in here as long as
-        * this function is always called from sys_ioctl i.e., de is
-         * a field of a struct file that is guaranteed not to be freed.
-        */
-       if (cmd == FIOC_SETIATTR) {
-               if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE))
-                       return -EPERM;
-               if (copy_from_user (&vc_data, data, sizeof(vc_data)))
-                       return -EFAULT;
-               ret = __vc_set_iattr(de,
-                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
-       }
-       else {
-               if (!vx_check(0, VS_ADMIN))
-                       return -ENOSYS;
-               ret = __vc_get_iattr(de->d_inode,
-                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
-       }
+       if (!capable(CAP_LINUX_IMMUTABLE))
+               return -EPERM;
+       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
+               return -EFAULT;
 
-       if (!ret && copy_to_user (data, &vc_data, sizeof(vc_data)))
-               ret = -EFAULT;
+       filp = fget(fd);
+       if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode)
+               return -EBADF;
+
+       ret = __vc_set_iattr(filp->f_dentry, &vc_data.xid,
+               &vc_data.flags, &vc_data.mask);
+
+       fput(filp);
+
+       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
+               return -EFAULT;
        return ret;
 }
 
index 67b3870..36e8968 100644 (file)
@@ -200,6 +200,11 @@ long do_vcmd(uint32_t cmd, uint32_t id,
        case VCMD_set_iattr:
                return __COMPAT(vc_set_iattr, id, data, compat);
 
+       case VCMD_fget_iattr:
+               return vc_fget_iattr(id, data);
+       case VCMD_fset_iattr:
+               return vc_fset_iattr(id, data);
+
        case VCMD_enter_space_v0:
                return vc_enter_space(vxi, NULL);
        /* this is version 1 */
@@ -308,6 +313,7 @@ long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
        __VCMD(get_nflags,       3, VCA_NXI,    VCF_INFO);
 
        __VCMD(get_iattr,        2, VCA_NONE,   0);
+       __VCMD(fget_iattr,       2, VCA_NONE,   0);
        __VCMD(get_dlimit,       3, VCA_NONE,   VCF_INFO);
        __VCMD(get_sched,        3, VCA_VXI,    VCF_INFO);
        __VCMD(sched_info,       3, VCA_VXI,    VCF_INFO|VCF_ZIDOK);
@@ -348,6 +354,7 @@ long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
        __VCMD(net_remove,       8, VCA_NXI,    VCF_ARES|VCF_SETUP);
 
        __VCMD(set_iattr,        7, VCA_NONE,   0);
+       __VCMD(fset_iattr,       7, VCA_NONE,   0);
        __VCMD(set_dlimit,       7, VCA_NONE,   VCF_ARES);
        __VCMD(add_dlimit,       8, VCA_NONE,   VCF_ARES);
        __VCMD(rem_dlimit,       8, VCA_NONE,   VCF_ARES);