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

Signed-off-by: Miklos Szeredi <mszer...@redhat.com>
Cc: Jan Kara <j...@suse.cz>
---
 fs/reiserfs/file.c     |   2 +
 fs/reiserfs/ioctl.c    | 120 +++++++++++++++++++----------------------
 fs/reiserfs/namei.c    |   2 +
 fs/reiserfs/reiserfs.h |   6 +--
 fs/reiserfs/super.c    |   2 +-
 5 files changed, 62 insertions(+), 70 deletions(-)

diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 0b641ae694f1..be86ddf898a9 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -258,4 +258,6 @@ const struct inode_operations 
reiserfs_file_inode_operations = {
        .permission = reiserfs_permission,
        .get_acl = reiserfs_get_acl,
        .set_acl = reiserfs_set_acl,
+       .miscattr_get = reiserfs_miscattr_get,
+       .miscattr_set = reiserfs_miscattr_set,
 };
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index adb21bea3d60..68f4cae19c59 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -10,6 +10,58 @@
 #include <linux/uaccess.h>
 #include <linux/pagemap.h>
 #include <linux/compat.h>
+#include <linux/miscattr.h>
+
+int reiserfs_miscattr_get(struct dentry *dentry, struct miscattr *ma)
+{
+       struct inode *inode = d_inode(dentry);
+
+       if (!reiserfs_attrs(inode->i_sb))
+               return -ENOTTY;
+
+       miscattr_fill_flags(ma, REISERFS_I(inode)->i_attrs);
+
+       return 0;
+}
+
+int reiserfs_miscattr_set(struct dentry *dentry, struct miscattr *ma)
+{
+       struct inode *inode = d_inode(dentry);
+       unsigned int flags = ma->flags;
+       int err;
+
+       reiserfs_write_lock(inode->i_sb);
+
+       err = -ENOTTY;
+       if (!reiserfs_attrs(inode->i_sb))
+               goto unlock;
+
+       err = -EOPNOTSUPP;
+       if (miscattr_has_xattr(ma))
+               goto unlock;
+
+       /*
+        * Is it quota file? Do not allow user to mess with it
+        */
+       err = -EPERM;
+       if (IS_NOQUOTA(inode))
+               goto unlock;
+
+       if ((flags & REISERFS_NOTAIL_FL) && S_ISREG(inode->i_mode)) {
+               err = reiserfs_unpack(inode);
+               if (err)
+                       goto unlock;
+       }
+       sd_attrs_to_i_attrs(flags, inode);
+       REISERFS_I(inode)->i_attrs = flags;
+       inode->i_ctime = current_time(inode);
+       mark_inode_dirty(inode);
+       err = 0;
+unlock:
+       reiserfs_write_unlock(inode->i_sb);
+
+       return err;
+}
 
 /*
  * reiserfs_ioctl - handler for ioctl for inode
@@ -23,7 +75,6 @@
 long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
-       unsigned int flags;
        int err = 0;
 
        reiserfs_write_lock(inode->i_sb);
@@ -32,7 +83,7 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
        case REISERFS_IOC_UNPACK:
                if (S_ISREG(inode->i_mode)) {
                        if (arg)
-                               err = reiserfs_unpack(inode, filp);
+                               err = reiserfs_unpack(inode);
                } else
                        err = -ENOTTY;
                break;
@@ -40,63 +91,6 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, 
unsigned long arg)
                 * following two cases are taken from fs/ext2/ioctl.c by Remy
                 * Card (c...@masi.ibp.fr)
                 */
-       case REISERFS_IOC_GETFLAGS:
-               if (!reiserfs_attrs(inode->i_sb)) {
-                       err = -ENOTTY;
-                       break;
-               }
-
-               flags = REISERFS_I(inode)->i_attrs;
-               err = put_user(flags, (int __user *)arg);
-               break;
-       case REISERFS_IOC_SETFLAGS:{
-                       if (!reiserfs_attrs(inode->i_sb)) {
-                               err = -ENOTTY;
-                               break;
-                       }
-
-                       err = mnt_want_write_file(filp);
-                       if (err)
-                               break;
-
-                       if (!inode_owner_or_capable(inode)) {
-                               err = -EPERM;
-                               goto setflags_out;
-                       }
-                       if (get_user(flags, (int __user *)arg)) {
-                               err = -EFAULT;
-                               goto setflags_out;
-                       }
-                       /*
-                        * Is it quota file? Do not allow user to mess with it
-                        */
-                       if (IS_NOQUOTA(inode)) {
-                               err = -EPERM;
-                               goto setflags_out;
-                       }
-                       err = vfs_ioc_setflags_prepare(inode,
-                                                    REISERFS_I(inode)->i_attrs,
-                                                    flags);
-                       if (err)
-                               goto setflags_out;
-                       if ((flags & REISERFS_NOTAIL_FL) &&
-                           S_ISREG(inode->i_mode)) {
-                               int result;
-
-                               result = reiserfs_unpack(inode, filp);
-                               if (result) {
-                                       err = result;
-                                       goto setflags_out;
-                               }
-                       }
-                       sd_attrs_to_i_attrs(flags, inode);
-                       REISERFS_I(inode)->i_attrs = flags;
-                       inode->i_ctime = current_time(inode);
-                       mark_inode_dirty(inode);
-setflags_out:
-                       mnt_drop_write_file(filp);
-                       break;
-               }
        case REISERFS_IOC_GETVERSION:
                err = put_user(inode->i_generation, (int __user *)arg);
                break;
@@ -138,12 +132,6 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int 
cmd,
        case REISERFS_IOC32_UNPACK:
                cmd = REISERFS_IOC_UNPACK;
                break;
-       case REISERFS_IOC32_GETFLAGS:
-               cmd = REISERFS_IOC_GETFLAGS;
-               break;
-       case REISERFS_IOC32_SETFLAGS:
-               cmd = REISERFS_IOC_SETFLAGS;
-               break;
        case REISERFS_IOC32_GETVERSION:
                cmd = REISERFS_IOC_GETVERSION;
                break;
@@ -165,7 +153,7 @@ int reiserfs_commit_write(struct file *f, struct page *page,
  * Function try to convert tail from direct item into indirect.
  * It set up nopack attribute in the REISERFS_I(inode)->nopack
  */
-int reiserfs_unpack(struct inode *inode, struct file *filp)
+int reiserfs_unpack(struct inode *inode)
 {
        int retval = 0;
        int index;
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 1594687582f0..d595b7f23fac 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1657,6 +1657,8 @@ const struct inode_operations 
reiserfs_dir_inode_operations = {
        .permission = reiserfs_permission,
        .get_acl = reiserfs_get_acl,
        .set_acl = reiserfs_set_acl,
+       .miscattr_get = reiserfs_miscattr_get,
+       .miscattr_set = reiserfs_miscattr_set,
 };
 
 /*
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h
index f69871516167..b7e06fbca65a 100644
--- a/fs/reiserfs/reiserfs.h
+++ b/fs/reiserfs/reiserfs.h
@@ -18,8 +18,6 @@
 
 /* the 32 bit compat definitions with int argument */
 #define REISERFS_IOC32_UNPACK          _IOW(0xCD, 1, int)
-#define REISERFS_IOC32_GETFLAGS                FS_IOC32_GETFLAGS
-#define REISERFS_IOC32_SETFLAGS                FS_IOC32_SETFLAGS
 #define REISERFS_IOC32_GETVERSION      FS_IOC32_GETVERSION
 #define REISERFS_IOC32_SETVERSION      FS_IOC32_SETVERSION
 
@@ -3407,7 +3405,9 @@ __u32 r5_hash(const signed char *msg, int len);
 #define SPARE_SPACE 500
 
 /* prototypes from ioctl.c */
+int reiserfs_miscattr_get(struct dentry *dentry, struct miscattr *ma);
+int reiserfs_miscattr_set(struct dentry *dentry, struct miscattr *ma);
 long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 long reiserfs_compat_ioctl(struct file *filp,
                   unsigned int cmd, unsigned long arg);
-int reiserfs_unpack(struct inode *inode, struct file *filp);
+int reiserfs_unpack(struct inode *inode);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 1b9c7a387dc7..3ffafc73acf0 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2408,7 +2408,7 @@ static int reiserfs_quota_on(struct super_block *sb, int 
type, int format_id,
         * IO to work
         */
        if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
-               err = reiserfs_unpack(inode, NULL);
+               err = reiserfs_unpack(inode);
                if (err) {
                        reiserfs_warning(sb, "super-6520",
                                "Unpacking tail of quota file failed"
-- 
2.26.2

Reply via email to