Use the miscattr API to let the VFS handle locking, permission checking and
conversion.

Signed-off-by: Miklos Szeredi <mszer...@redhat.com>
Cc: Mike Marshall <hub...@omnibond.com>
---
 fs/orangefs/file.c  | 79 ---------------------------------------------
 fs/orangefs/inode.c | 49 ++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 79 deletions(-)

diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c
index ec8ae4257975..8958bf9c5786 100644
--- a/fs/orangefs/file.c
+++ b/fs/orangefs/file.c
@@ -375,84 +375,6 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb,
        return ret;
 }
 
-static int orangefs_getflags(struct inode *inode, unsigned long *uval)
-{
-       __u64 val = 0;
-       int ret;
-
-       ret = orangefs_inode_getxattr(inode,
-                                     "user.pvfs2.meta_hint",
-                                     &val, sizeof(val));
-       if (ret < 0 && ret != -ENODATA)
-               return ret;
-       else if (ret == -ENODATA)
-               val = 0;
-       *uval = val;
-       return 0;
-}
-
-/*
- * Perform a miscellaneous operation on a file.
- */
-static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long 
arg)
-{
-       struct inode *inode = file_inode(file);
-       int ret = -ENOTTY;
-       __u64 val = 0;
-       unsigned long uval;
-
-       gossip_debug(GOSSIP_FILE_DEBUG,
-                    "orangefs_ioctl: called with cmd %d\n",
-                    cmd);
-
-       /*
-        * we understand some general ioctls on files, such as the immutable
-        * and append flags
-        */
-       if (cmd == FS_IOC_GETFLAGS) {
-               ret = orangefs_getflags(inode, &uval);
-               if (ret)
-                       return ret;
-               gossip_debug(GOSSIP_FILE_DEBUG,
-                            "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
-                            (unsigned long long)uval);
-               return put_user(uval, (int __user *)arg);
-       } else if (cmd == FS_IOC_SETFLAGS) {
-               unsigned long old_uval;
-
-               ret = 0;
-               if (get_user(uval, (int __user *)arg))
-                       return -EFAULT;
-               /*
-                * ORANGEFS_MIRROR_FL is set internally when the mirroring mode
-                * is turned on for a file. The user is not allowed to turn
-                * on this bit, but the bit is present if the user first gets
-                * the flags and then updates the flags with some new
-                * settings. So, we ignore it in the following edit. bligon.
-                */
-               if ((uval & ~ORANGEFS_MIRROR_FL) &
-                   (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
-                       gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only 
supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
-                       return -EINVAL;
-               }
-               ret = orangefs_getflags(inode, &old_uval);
-               if (ret)
-                       return ret;
-               ret = vfs_ioc_setflags_prepare(inode, old_uval, uval);
-               if (ret)
-                       return ret;
-               val = uval;
-               gossip_debug(GOSSIP_FILE_DEBUG,
-                            "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
-                            (unsigned long long)val);
-               ret = orangefs_inode_setxattr(inode,
-                                             "user.pvfs2.meta_hint",
-                                             &val, sizeof(val), 0);
-       }
-
-       return ret;
-}
-
 static vm_fault_t orangefs_fault(struct vm_fault *vmf)
 {
        struct file *file = vmf->vma->vm_file;
@@ -660,7 +582,6 @@ const struct file_operations orangefs_file_operations = {
        .read_iter      = orangefs_file_read_iter,
        .write_iter     = orangefs_file_write_iter,
        .lock           = orangefs_lock,
-       .unlocked_ioctl = orangefs_ioctl,
        .mmap           = orangefs_file_mmap,
        .open           = generic_file_open,
        .splice_read    = generic_file_splice_read,
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 48f0547d4850..84461d2229ac 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/bvec.h>
+#include <linux/miscattr.h>
 #include "protocol.h"
 #include "orangefs-kernel.h"
 #include "orangefs-bufmap.h"
@@ -952,6 +953,52 @@ int orangefs_update_time(struct inode *inode, struct 
timespec64 *time, int flags
        return __orangefs_setattr(inode, &iattr);
 }
 
+static int orangefs_miscattr_get(struct dentry *dentry, struct miscattr *ma)
+{
+       u64 val = 0;
+       int ret;
+
+       gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__,
+                    dentry);
+
+       ret = orangefs_inode_getxattr(d_inode(dentry),
+                                     "user.pvfs2.meta_hint",
+                                     &val, sizeof(val));
+       if (ret < 0 && ret != -ENODATA)
+               return ret;
+
+       gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val);
+
+       miscattr_fill_flags(ma, val);
+       return 0;
+}
+
+static int orangefs_miscattr_set(struct dentry *dentry, struct miscattr *ma)
+{
+       u64 val = 0;
+
+       gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__,
+                    dentry);
+       /*
+        * ORANGEFS_MIRROR_FL is set internally when the mirroring mode is
+        * turned on for a file. The user is not allowed to turn on this bit,
+        * but the bit is present if the user first gets the flags and then
+        * updates the flags with some new settings. So, we ignore it in the
+        * following edit. bligon.
+        */
+       if (miscattr_has_xattr(ma) ||
+           (ma->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL | 
ORANGEFS_MIRROR_FL))) {
+               gossip_err("%s: only supports setting one of 
FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n",
+                          __func__);
+               return -EOPNOTSUPP;
+       }
+       val = ma->flags;
+       gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val);
+       return orangefs_inode_setxattr(d_inode(dentry),
+                                      "user.pvfs2.meta_hint",
+                                      &val, sizeof(val), 0);
+}
+
 /* ORANGEFS2 implementation of VFS inode operations for files */
 static const struct inode_operations orangefs_file_inode_operations = {
        .get_acl = orangefs_get_acl,
@@ -961,6 +1008,8 @@ static const struct inode_operations 
orangefs_file_inode_operations = {
        .listxattr = orangefs_listxattr,
        .permission = orangefs_permission,
        .update_time = orangefs_update_time,
+       .miscattr_get = orangefs_miscattr_get,
+       .miscattr_set = orangefs_miscattr_set,
 };
 
 static int orangefs_init_iops(struct inode *inode)
-- 
2.26.2

Reply via email to