linux/fs/configfs/inode.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* -*- mode: c; c-basic-offset: 8; -*-
   3 * vim: noexpandtab sw=8 ts=8 sts=0:
   4 *
   5 * inode.c - basic inode and dentry operations.
   6 *
   7 * Based on sysfs:
   8 *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
   9 *
  10 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  11 *
  12 * Please see Documentation/filesystems/configfs.rst for more
  13 * information.
  14 */
  15
  16#undef DEBUG
  17
  18#include <linux/pagemap.h>
  19#include <linux/namei.h>
  20#include <linux/backing-dev.h>
  21#include <linux/capability.h>
  22#include <linux/sched.h>
  23#include <linux/lockdep.h>
  24#include <linux/slab.h>
  25
  26#include <linux/configfs.h>
  27#include "configfs_internal.h"
  28
  29#ifdef CONFIG_LOCKDEP
  30static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
  31#endif
  32
  33static const struct address_space_operations configfs_aops = {
  34        .readpage       = simple_readpage,
  35        .write_begin    = simple_write_begin,
  36        .write_end      = simple_write_end,
  37};
  38
  39static const struct inode_operations configfs_inode_operations ={
  40        .setattr        = configfs_setattr,
  41};
  42
  43int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
  44{
  45        struct inode * inode = d_inode(dentry);
  46        struct configfs_dirent * sd = dentry->d_fsdata;
  47        struct iattr * sd_iattr;
  48        unsigned int ia_valid = iattr->ia_valid;
  49        int error;
  50
  51        if (!sd)
  52                return -EINVAL;
  53
  54        sd_iattr = sd->s_iattr;
  55        if (!sd_iattr) {
  56                /* setting attributes for the first time, allocate now */
  57                sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
  58                if (!sd_iattr)
  59                        return -ENOMEM;
  60                /* assign default attributes */
  61                sd_iattr->ia_mode = sd->s_mode;
  62                sd_iattr->ia_uid = GLOBAL_ROOT_UID;
  63                sd_iattr->ia_gid = GLOBAL_ROOT_GID;
  64                sd_iattr->ia_atime = sd_iattr->ia_mtime =
  65                        sd_iattr->ia_ctime = current_time(inode);
  66                sd->s_iattr = sd_iattr;
  67        }
  68        /* attributes were changed atleast once in past */
  69
  70        error = simple_setattr(dentry, iattr);
  71        if (error)
  72                return error;
  73
  74        if (ia_valid & ATTR_UID)
  75                sd_iattr->ia_uid = iattr->ia_uid;
  76        if (ia_valid & ATTR_GID)
  77                sd_iattr->ia_gid = iattr->ia_gid;
  78        if (ia_valid & ATTR_ATIME)
  79                sd_iattr->ia_atime = iattr->ia_atime;
  80        if (ia_valid & ATTR_MTIME)
  81                sd_iattr->ia_mtime = iattr->ia_mtime;
  82        if (ia_valid & ATTR_CTIME)
  83                sd_iattr->ia_ctime = iattr->ia_ctime;
  84        if (ia_valid & ATTR_MODE) {
  85                umode_t mode = iattr->ia_mode;
  86
  87                if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
  88                        mode &= ~S_ISGID;
  89                sd_iattr->ia_mode = sd->s_mode = mode;
  90        }
  91
  92        return error;
  93}
  94
  95static inline void set_default_inode_attr(struct inode * inode, umode_t mode)
  96{
  97        inode->i_mode = mode;
  98        inode->i_atime = inode->i_mtime =
  99                inode->i_ctime = current_time(inode);
 100}
 101
 102static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
 103{
 104        inode->i_mode = iattr->ia_mode;
 105        inode->i_uid = iattr->ia_uid;
 106        inode->i_gid = iattr->ia_gid;
 107        inode->i_atime = iattr->ia_atime;
 108        inode->i_mtime = iattr->ia_mtime;
 109        inode->i_ctime = iattr->ia_ctime;
 110}
 111
 112struct inode *configfs_new_inode(umode_t mode, struct configfs_dirent *sd,
 113                                 struct super_block *s)
 114{
 115        struct inode * inode = new_inode(s);
 116        if (inode) {
 117                inode->i_ino = get_next_ino();
 118                inode->i_mapping->a_ops = &configfs_aops;
 119                inode->i_op = &configfs_inode_operations;
 120
 121                if (sd->s_iattr) {
 122                        /* sysfs_dirent has non-default attributes
 123                         * get them for the new inode from persistent copy
 124                         * in sysfs_dirent
 125                         */
 126                        set_inode_attr(inode, sd->s_iattr);
 127                } else
 128                        set_default_inode_attr(inode, mode);
 129        }
 130        return inode;
 131}
 132
 133#ifdef CONFIG_LOCKDEP
 134
 135static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
 136                                          struct inode *inode)
 137{
 138        int depth = sd->s_depth;
 139
 140        if (depth > 0) {
 141                if (depth <= ARRAY_SIZE(default_group_class)) {
 142                        lockdep_set_class(&inode->i_rwsem,
 143                                          &default_group_class[depth - 1]);
 144                } else {
 145                        /*
 146                         * In practice the maximum level of locking depth is
 147                         * already reached. Just inform about possible reasons.
 148                         */
 149                        pr_info("Too many levels of inodes for the locking correctness validator.\n");
 150                        pr_info("Spurious warnings may appear.\n");
 151                }
 152        }
 153}
 154
 155#else /* CONFIG_LOCKDEP */
 156
 157static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
 158                                          struct inode *inode)
 159{
 160}
 161
 162#endif /* CONFIG_LOCKDEP */
 163
 164struct inode *configfs_create(struct dentry *dentry, umode_t mode)
 165{
 166        struct inode *inode = NULL;
 167        struct configfs_dirent *sd;
 168        struct inode *p_inode;
 169
 170        if (!dentry)
 171                return ERR_PTR(-ENOENT);
 172
 173        if (d_really_is_positive(dentry))
 174                return ERR_PTR(-EEXIST);
 175
 176        sd = dentry->d_fsdata;
 177        inode = configfs_new_inode(mode, sd, dentry->d_sb);
 178        if (!inode)
 179                return ERR_PTR(-ENOMEM);
 180
 181        p_inode = d_inode(dentry->d_parent);
 182        p_inode->i_mtime = p_inode->i_ctime = current_time(p_inode);
 183        configfs_set_inode_lock_class(sd, inode);
 184        return inode;
 185}
 186
 187/*
 188 * Get the name for corresponding element represented by the given configfs_dirent
 189 */
 190const unsigned char * configfs_get_name(struct configfs_dirent *sd)
 191{
 192        struct configfs_attribute *attr;
 193
 194        BUG_ON(!sd || !sd->s_element);
 195
 196        /* These always have a dentry, so use that */
 197        if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
 198                return sd->s_dentry->d_name.name;
 199
 200        if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) {
 201                attr = sd->s_element;
 202                return attr->ca_name;
 203        }
 204        return NULL;
 205}
 206
 207
 208/*
 209 * Unhashes the dentry corresponding to given configfs_dirent
 210 * Called with parent inode's i_mutex held.
 211 */
 212void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
 213{
 214        struct dentry * dentry = sd->s_dentry;
 215
 216        if (dentry) {
 217                spin_lock(&dentry->d_lock);
 218                if (simple_positive(dentry)) {
 219                        dget_dlock(dentry);
 220                        __d_drop(dentry);
 221                        spin_unlock(&dentry->d_lock);
 222                        simple_unlink(d_inode(parent), dentry);
 223                } else
 224                        spin_unlock(&dentry->d_lock);
 225        }
 226}
 227
 228void configfs_hash_and_remove(struct dentry * dir, const char * name)
 229{
 230        struct configfs_dirent * sd;
 231        struct configfs_dirent * parent_sd = dir->d_fsdata;
 232
 233        if (d_really_is_negative(dir))
 234                /* no inode means this hasn't been made visible yet */
 235                return;
 236
 237        inode_lock(d_inode(dir));
 238        list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 239                if (!sd->s_element)
 240                        continue;
 241                if (!strcmp(configfs_get_name(sd), name)) {
 242                        spin_lock(&configfs_dirent_lock);
 243                        list_del_init(&sd->s_sibling);
 244                        spin_unlock(&configfs_dirent_lock);
 245                        configfs_drop_dentry(sd, dir);
 246                        configfs_put(sd);
 247                        break;
 248                }
 249        }
 250        inode_unlock(d_inode(dir));
 251}
 252