linux/fs/kernfs/mount.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * fs/kernfs/mount.c - kernfs mount implementation
   4 *
   5 * Copyright (c) 2001-3 Patrick Mochel
   6 * Copyright (c) 2007 SUSE Linux Products GmbH
   7 * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
   8 */
   9
  10#include <linux/fs.h>
  11#include <linux/mount.h>
  12#include <linux/init.h>
  13#include <linux/magic.h>
  14#include <linux/slab.h>
  15#include <linux/pagemap.h>
  16#include <linux/namei.h>
  17#include <linux/seq_file.h>
  18#include <linux/exportfs.h>
  19
  20#include "kernfs-internal.h"
  21
  22struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache;
  23
  24static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry)
  25{
  26        struct kernfs_root *root = kernfs_root(kernfs_dentry_node(dentry));
  27        struct kernfs_syscall_ops *scops = root->syscall_ops;
  28
  29        if (scops && scops->show_options)
  30                return scops->show_options(sf, root);
  31        return 0;
  32}
  33
  34static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)
  35{
  36        struct kernfs_node *node = kernfs_dentry_node(dentry);
  37        struct kernfs_root *root = kernfs_root(node);
  38        struct kernfs_syscall_ops *scops = root->syscall_ops;
  39
  40        if (scops && scops->show_path)
  41                return scops->show_path(sf, node, root);
  42
  43        seq_dentry(sf, dentry, " \t\n\\");
  44        return 0;
  45}
  46
  47const struct super_operations kernfs_sops = {
  48        .statfs         = simple_statfs,
  49        .drop_inode     = generic_delete_inode,
  50        .evict_inode    = kernfs_evict_inode,
  51
  52        .show_options   = kernfs_sop_show_options,
  53        .show_path      = kernfs_sop_show_path,
  54};
  55
  56static int kernfs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
  57                            struct inode *parent)
  58{
  59        struct kernfs_node *kn = inode->i_private;
  60
  61        if (*max_len < 2) {
  62                *max_len = 2;
  63                return FILEID_INVALID;
  64        }
  65
  66        *max_len = 2;
  67        *(u64 *)fh = kn->id;
  68        return FILEID_KERNFS;
  69}
  70
  71static struct dentry *__kernfs_fh_to_dentry(struct super_block *sb,
  72                                            struct fid *fid, int fh_len,
  73                                            int fh_type, bool get_parent)
  74{
  75        struct kernfs_super_info *info = kernfs_info(sb);
  76        struct kernfs_node *kn;
  77        struct inode *inode;
  78        u64 id;
  79
  80        if (fh_len < 2)
  81                return NULL;
  82
  83        switch (fh_type) {
  84        case FILEID_KERNFS:
  85                id = *(u64 *)fid;
  86                break;
  87        case FILEID_INO32_GEN:
  88        case FILEID_INO32_GEN_PARENT:
  89                /*
  90                 * blk_log_action() exposes "LOW32,HIGH32" pair without
  91                 * type and userland can call us with generic fid
  92                 * constructed from them.  Combine it back to ID.  See
  93                 * blk_log_action().
  94                 */
  95                id = ((u64)fid->i32.gen << 32) | fid->i32.ino;
  96                break;
  97        default:
  98                return NULL;
  99        }
 100
 101        kn = kernfs_find_and_get_node_by_id(info->root, id);
 102        if (!kn)
 103                return ERR_PTR(-ESTALE);
 104
 105        if (get_parent) {
 106                struct kernfs_node *parent;
 107
 108                parent = kernfs_get_parent(kn);
 109                kernfs_put(kn);
 110                kn = parent;
 111                if (!kn)
 112                        return ERR_PTR(-ESTALE);
 113        }
 114
 115        inode = kernfs_get_inode(sb, kn);
 116        kernfs_put(kn);
 117        if (!inode)
 118                return ERR_PTR(-ESTALE);
 119
 120        return d_obtain_alias(inode);
 121}
 122
 123static struct dentry *kernfs_fh_to_dentry(struct super_block *sb,
 124                                          struct fid *fid, int fh_len,
 125                                          int fh_type)
 126{
 127        return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, false);
 128}
 129
 130static struct dentry *kernfs_fh_to_parent(struct super_block *sb,
 131                                          struct fid *fid, int fh_len,
 132                                          int fh_type)
 133{
 134        return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, true);
 135}
 136
 137static struct dentry *kernfs_get_parent_dentry(struct dentry *child)
 138{
 139        struct kernfs_node *kn = kernfs_dentry_node(child);
 140
 141        return d_obtain_alias(kernfs_get_inode(child->d_sb, kn->parent));
 142}
 143
 144static const struct export_operations kernfs_export_ops = {
 145        .encode_fh      = kernfs_encode_fh,
 146        .fh_to_dentry   = kernfs_fh_to_dentry,
 147        .fh_to_parent   = kernfs_fh_to_parent,
 148        .get_parent     = kernfs_get_parent_dentry,
 149};
 150
 151/**
 152 * kernfs_root_from_sb - determine kernfs_root associated with a super_block
 153 * @sb: the super_block in question
 154 *
 155 * Return the kernfs_root associated with @sb.  If @sb is not a kernfs one,
 156 * %NULL is returned.
 157 */
 158struct kernfs_root *kernfs_root_from_sb(struct super_block *sb)
 159{
 160        if (sb->s_op == &kernfs_sops)
 161                return kernfs_info(sb)->root;
 162        return NULL;
 163}
 164
 165/*
 166 * find the next ancestor in the path down to @child, where @parent was the
 167 * ancestor whose descendant we want to find.
 168 *
 169 * Say the path is /a/b/c/d.  @child is d, @parent is NULL.  We return the root
 170 * node.  If @parent is b, then we return the node for c.
 171 * Passing in d as @parent is not ok.
 172 */
 173static struct kernfs_node *find_next_ancestor(struct kernfs_node *child,
 174                                              struct kernfs_node *parent)
 175{
 176        if (child == parent) {
 177                pr_crit_once("BUG in find_next_ancestor: called with parent == child");
 178                return NULL;
 179        }
 180
 181        while (child->parent != parent) {
 182                if (!child->parent)
 183                        return NULL;
 184                child = child->parent;
 185        }
 186
 187        return child;
 188}
 189
 190/**
 191 * kernfs_node_dentry - get a dentry for the given kernfs_node
 192 * @kn: kernfs_node for which a dentry is needed
 193 * @sb: the kernfs super_block
 194 */
 195struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
 196                                  struct super_block *sb)
 197{
 198        struct dentry *dentry;
 199        struct kernfs_node *knparent = NULL;
 200
 201        BUG_ON(sb->s_op != &kernfs_sops);
 202
 203        dentry = dget(sb->s_root);
 204
 205        /* Check if this is the root kernfs_node */
 206        if (!kn->parent)
 207                return dentry;
 208
 209        knparent = find_next_ancestor(kn, NULL);
 210        if (WARN_ON(!knparent)) {
 211                dput(dentry);
 212                return ERR_PTR(-EINVAL);
 213        }
 214
 215        do {
 216                struct dentry *dtmp;
 217                struct kernfs_node *kntmp;
 218
 219                if (kn == knparent)
 220                        return dentry;
 221                kntmp = find_next_ancestor(kn, knparent);
 222                if (WARN_ON(!kntmp)) {
 223                        dput(dentry);
 224                        return ERR_PTR(-EINVAL);
 225                }
 226                dtmp = lookup_positive_unlocked(kntmp->name, dentry,
 227                                               strlen(kntmp->name));
 228                dput(dentry);
 229                if (IS_ERR(dtmp))
 230                        return dtmp;
 231                knparent = kntmp;
 232                dentry = dtmp;
 233        } while (true);
 234}
 235
 236static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
 237{
 238        struct kernfs_super_info *info = kernfs_info(sb);
 239        struct inode *inode;
 240        struct dentry *root;
 241
 242        info->sb = sb;
 243        /* Userspace would break if executables or devices appear on sysfs */
 244        sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
 245        sb->s_blocksize = PAGE_SIZE;
 246        sb->s_blocksize_bits = PAGE_SHIFT;
 247        sb->s_magic = kfc->magic;
 248        sb->s_op = &kernfs_sops;
 249        sb->s_xattr = kernfs_xattr_handlers;
 250        if (info->root->flags & KERNFS_ROOT_SUPPORT_EXPORTOP)
 251                sb->s_export_op = &kernfs_export_ops;
 252        sb->s_time_gran = 1;
 253
 254        /* sysfs dentries and inodes don't require IO to create */
 255        sb->s_shrink.seeks = 0;
 256
 257        /* get root inode, initialize and unlock it */
 258        down_read(&kernfs_rwsem);
 259        inode = kernfs_get_inode(sb, info->root->kn);
 260        up_read(&kernfs_rwsem);
 261        if (!inode) {
 262                pr_debug("kernfs: could not get root inode\n");
 263                return -ENOMEM;
 264        }
 265
 266        /* instantiate and link root dentry */
 267        root = d_make_root(inode);
 268        if (!root) {
 269                pr_debug("%s: could not get root dentry!\n", __func__);
 270                return -ENOMEM;
 271        }
 272        sb->s_root = root;
 273        sb->s_d_op = &kernfs_dops;
 274        return 0;
 275}
 276
 277static int kernfs_test_super(struct super_block *sb, struct fs_context *fc)
 278{
 279        struct kernfs_super_info *sb_info = kernfs_info(sb);
 280        struct kernfs_super_info *info = fc->s_fs_info;
 281
 282        return sb_info->root == info->root && sb_info->ns == info->ns;
 283}
 284
 285static int kernfs_set_super(struct super_block *sb, struct fs_context *fc)
 286{
 287        struct kernfs_fs_context *kfc = fc->fs_private;
 288
 289        kfc->ns_tag = NULL;
 290        return set_anon_super_fc(sb, fc);
 291}
 292
 293/**
 294 * kernfs_super_ns - determine the namespace tag of a kernfs super_block
 295 * @sb: super_block of interest
 296 *
 297 * Return the namespace tag associated with kernfs super_block @sb.
 298 */
 299const void *kernfs_super_ns(struct super_block *sb)
 300{
 301        struct kernfs_super_info *info = kernfs_info(sb);
 302
 303        return info->ns;
 304}
 305
 306/**
 307 * kernfs_get_tree - kernfs filesystem access/retrieval helper
 308 * @fc: The filesystem context.
 309 *
 310 * This is to be called from each kernfs user's fs_context->ops->get_tree()
 311 * implementation, which should set the specified ->@fs_type and ->@flags, and
 312 * specify the hierarchy and namespace tag to mount via ->@root and ->@ns,
 313 * respectively.
 314 */
 315int kernfs_get_tree(struct fs_context *fc)
 316{
 317        struct kernfs_fs_context *kfc = fc->fs_private;
 318        struct super_block *sb;
 319        struct kernfs_super_info *info;
 320        int error;
 321
 322        info = kzalloc(sizeof(*info), GFP_KERNEL);
 323        if (!info)
 324                return -ENOMEM;
 325
 326        info->root = kfc->root;
 327        info->ns = kfc->ns_tag;
 328        INIT_LIST_HEAD(&info->node);
 329
 330        fc->s_fs_info = info;
 331        sb = sget_fc(fc, kernfs_test_super, kernfs_set_super);
 332        if (IS_ERR(sb))
 333                return PTR_ERR(sb);
 334
 335        if (!sb->s_root) {
 336                struct kernfs_super_info *info = kernfs_info(sb);
 337
 338                kfc->new_sb_created = true;
 339
 340                error = kernfs_fill_super(sb, kfc);
 341                if (error) {
 342                        deactivate_locked_super(sb);
 343                        return error;
 344                }
 345                sb->s_flags |= SB_ACTIVE;
 346
 347                down_write(&kernfs_rwsem);
 348                list_add(&info->node, &info->root->supers);
 349                up_write(&kernfs_rwsem);
 350        }
 351
 352        fc->root = dget(sb->s_root);
 353        return 0;
 354}
 355
 356void kernfs_free_fs_context(struct fs_context *fc)
 357{
 358        /* Note that we don't deal with kfc->ns_tag here. */
 359        kfree(fc->s_fs_info);
 360        fc->s_fs_info = NULL;
 361}
 362
 363/**
 364 * kernfs_kill_sb - kill_sb for kernfs
 365 * @sb: super_block being killed
 366 *
 367 * This can be used directly for file_system_type->kill_sb().  If a kernfs
 368 * user needs extra cleanup, it can implement its own kill_sb() and call
 369 * this function at the end.
 370 */
 371void kernfs_kill_sb(struct super_block *sb)
 372{
 373        struct kernfs_super_info *info = kernfs_info(sb);
 374
 375        down_write(&kernfs_rwsem);
 376        list_del(&info->node);
 377        up_write(&kernfs_rwsem);
 378
 379        /*
 380         * Remove the superblock from fs_supers/s_instances
 381         * so we can't find it, before freeing kernfs_super_info.
 382         */
 383        kill_anon_super(sb);
 384        kfree(info);
 385}
 386
 387void __init kernfs_init(void)
 388{
 389        kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
 390                                              sizeof(struct kernfs_node),
 391                                              0, SLAB_PANIC, NULL);
 392
 393        /* Creates slab cache for kernfs inode attributes */
 394        kernfs_iattrs_cache  = kmem_cache_create("kernfs_iattrs_cache",
 395                                              sizeof(struct kernfs_iattrs),
 396                                              0, SLAB_PANIC, NULL);
 397}
 398