lkml.org 
[lkml]   [2021]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 11/18] efivars: convert to miscattr
    Date
    Use the miscattr API to let the VFS handle locking, permission checking and
    conversion.

    Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
    Cc: Matthew Garrett <matthew.garrett@nebula.com>
    ---
    fs/efivarfs/file.c | 77 ---------------------------------------------
    fs/efivarfs/inode.c | 43 +++++++++++++++++++++++++
    2 files changed, 43 insertions(+), 77 deletions(-)

    diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c
    index feaa5e182b7b..d57ee15874f9 100644
    --- a/fs/efivarfs/file.c
    +++ b/fs/efivarfs/file.c
    @@ -106,86 +106,9 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
    return size;
    }

    -static inline unsigned int efivarfs_getflags(struct inode *inode)
    -{
    - unsigned int i_flags;
    - unsigned int flags = 0;
    -
    - i_flags = inode->i_flags;
    - if (i_flags & S_IMMUTABLE)
    - flags |= FS_IMMUTABLE_FL;
    - return flags;
    -}
    -
    -static int
    -efivarfs_ioc_getxflags(struct file *file, void __user *arg)
    -{
    - struct inode *inode = file->f_mapping->host;
    - unsigned int flags = efivarfs_getflags(inode);
    -
    - if (copy_to_user(arg, &flags, sizeof(flags)))
    - return -EFAULT;
    - return 0;
    -}
    -
    -static int
    -efivarfs_ioc_setxflags(struct file *file, void __user *arg)
    -{
    - struct inode *inode = file->f_mapping->host;
    - unsigned int flags;
    - unsigned int i_flags = 0;
    - unsigned int oldflags = efivarfs_getflags(inode);
    - int error;
    -
    - if (!inode_owner_or_capable(inode))
    - return -EACCES;
    -
    - if (copy_from_user(&flags, arg, sizeof(flags)))
    - return -EFAULT;
    -
    - if (flags & ~FS_IMMUTABLE_FL)
    - return -EOPNOTSUPP;
    -
    - if (flags & FS_IMMUTABLE_FL)
    - i_flags |= S_IMMUTABLE;
    -
    -
    - error = mnt_want_write_file(file);
    - if (error)
    - return error;
    -
    - inode_lock(inode);
    -
    - error = vfs_ioc_setflags_prepare(inode, oldflags, flags);
    - if (error)
    - goto out;
    -
    - inode_set_flags(inode, i_flags, S_IMMUTABLE);
    -out:
    - inode_unlock(inode);
    - mnt_drop_write_file(file);
    - return error;
    -}
    -
    -static long
    -efivarfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long p)
    -{
    - void __user *arg = (void __user *)p;
    -
    - switch (cmd) {
    - case FS_IOC_GETFLAGS:
    - return efivarfs_ioc_getxflags(file, arg);
    - case FS_IOC_SETFLAGS:
    - return efivarfs_ioc_setxflags(file, arg);
    - }
    -
    - return -ENOTTY;
    -}
    -
    const struct file_operations efivarfs_file_operations = {
    .open = simple_open,
    .read = efivarfs_file_read,
    .write = efivarfs_file_write,
    .llseek = no_llseek,
    - .unlocked_ioctl = efivarfs_file_ioctl,
    };
    diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c
    index 0297ad95eb5c..35d9aba303a4 100644
    --- a/fs/efivarfs/inode.c
    +++ b/fs/efivarfs/inode.c
    @@ -10,9 +10,12 @@
    #include <linux/kmemleak.h>
    #include <linux/slab.h>
    #include <linux/uuid.h>
    +#include <linux/miscattr.h>

    #include "internal.h"

    +static const struct inode_operations efivarfs_file_inode_operations;
    +
    struct inode *efivarfs_get_inode(struct super_block *sb,
    const struct inode *dir, int mode,
    dev_t dev, bool is_removable)
    @@ -26,6 +29,7 @@ struct inode *efivarfs_get_inode(struct super_block *sb,
    inode->i_flags = is_removable ? 0 : S_IMMUTABLE;
    switch (mode & S_IFMT) {
    case S_IFREG:
    + inode->i_op = &efivarfs_file_inode_operations;
    inode->i_fop = &efivarfs_file_operations;
    break;
    case S_IFDIR:
    @@ -138,3 +142,42 @@ const struct inode_operations efivarfs_dir_inode_operations = {
    .unlink = efivarfs_unlink,
    .create = efivarfs_create,
    };
    +
    +static int
    +efivarfs_miscattr_get(struct dentry *dentry, struct miscattr *ma)
    +{
    + unsigned int i_flags;
    + unsigned int flags = 0;
    +
    + i_flags = d_inode(dentry)->i_flags;
    + if (i_flags & S_IMMUTABLE)
    + flags |= FS_IMMUTABLE_FL;
    +
    + miscattr_fill_flags(ma, flags);
    +
    + return 0;
    +}
    +
    +static int
    +efivarfs_miscattr_set(struct dentry *dentry, struct miscattr *ma)
    +{
    + unsigned int i_flags = 0;
    +
    + if (miscattr_has_xattr(ma))
    + return -EOPNOTSUPP;
    +
    + if (ma->flags & ~FS_IMMUTABLE_FL)
    + return -EOPNOTSUPP;
    +
    + if (ma->flags & FS_IMMUTABLE_FL)
    + i_flags |= S_IMMUTABLE;
    +
    + inode_set_flags(d_inode(dentry), i_flags, S_IMMUTABLE);
    +
    + return 0;
    +}
    +
    +static const struct inode_operations efivarfs_file_inode_operations = {
    + .miscattr_get = efivarfs_miscattr_get,
    + .miscattr_set = efivarfs_miscattr_set,
    +};
    --
    2.26.2
    \
     
     \ /
      Last update: 2021-02-03 14:00    [W:4.701 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site