linux/include/linux/fs_context.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/* Filesystem superblock creation and reconfiguration context.
   3 *
   4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#ifndef _LINUX_FS_CONTEXT_H
   9#define _LINUX_FS_CONTEXT_H
  10
  11#include <linux/kernel.h>
  12#include <linux/refcount.h>
  13#include <linux/errno.h>
  14#include <linux/security.h>
  15#include <linux/mutex.h>
  16
  17struct cred;
  18struct dentry;
  19struct file_operations;
  20struct file_system_type;
  21struct mnt_namespace;
  22struct net;
  23struct pid_namespace;
  24struct super_block;
  25struct user_namespace;
  26struct vfsmount;
  27struct path;
  28
  29enum fs_context_purpose {
  30        FS_CONTEXT_FOR_MOUNT,           /* New superblock for explicit mount */
  31        FS_CONTEXT_FOR_SUBMOUNT,        /* New superblock for automatic submount */
  32        FS_CONTEXT_FOR_RECONFIGURE,     /* Superblock reconfiguration (remount) */
  33};
  34
  35/*
  36 * Userspace usage phase for fsopen/fspick.
  37 */
  38enum fs_context_phase {
  39        FS_CONTEXT_CREATE_PARAMS,       /* Loading params for sb creation */
  40        FS_CONTEXT_CREATING,            /* A superblock is being created */
  41        FS_CONTEXT_AWAITING_MOUNT,      /* Superblock created, awaiting fsmount() */
  42        FS_CONTEXT_AWAITING_RECONF,     /* Awaiting initialisation for reconfiguration */
  43        FS_CONTEXT_RECONF_PARAMS,       /* Loading params for reconfiguration */
  44        FS_CONTEXT_RECONFIGURING,       /* Reconfiguring the superblock */
  45        FS_CONTEXT_FAILED,              /* Failed to correctly transition a context */
  46};
  47
  48/*
  49 * Type of parameter value.
  50 */
  51enum fs_value_type {
  52        fs_value_is_undefined,
  53        fs_value_is_flag,               /* Value not given a value */
  54        fs_value_is_string,             /* Value is a string */
  55        fs_value_is_blob,               /* Value is a binary blob */
  56        fs_value_is_filename,           /* Value is a filename* + dirfd */
  57        fs_value_is_file,               /* Value is a file* */
  58};
  59
  60/*
  61 * Configuration parameter.
  62 */
  63struct fs_parameter {
  64        const char              *key;           /* Parameter name */
  65        enum fs_value_type      type:8;         /* The type of value here */
  66        union {
  67                char            *string;
  68                void            *blob;
  69                struct filename *name;
  70                struct file     *file;
  71        };
  72        size_t  size;
  73        int     dirfd;
  74};
  75
  76struct p_log {
  77        const char *prefix;
  78        struct fc_log *log;
  79};
  80
  81/*
  82 * Filesystem context for holding the parameters used in the creation or
  83 * reconfiguration of a superblock.
  84 *
  85 * Superblock creation fills in ->root whereas reconfiguration begins with this
  86 * already set.
  87 *
  88 * See Documentation/filesystems/mount_api.rst
  89 */
  90struct fs_context {
  91        const struct fs_context_operations *ops;
  92        struct mutex            uapi_mutex;     /* Userspace access mutex */
  93        struct file_system_type *fs_type;
  94        void                    *fs_private;    /* The filesystem's context */
  95        void                    *sget_key;
  96        struct dentry           *root;          /* The root and superblock */
  97        struct user_namespace   *user_ns;       /* The user namespace for this mount */
  98        struct net              *net_ns;        /* The network namespace for this mount */
  99        const struct cred       *cred;          /* The mounter's credentials */
 100        struct p_log            log;            /* Logging buffer */
 101        const char              *source;        /* The source name (eg. dev path) */
 102        void                    *security;      /* Linux S&M options */
 103        void                    *s_fs_info;     /* Proposed s_fs_info */
 104        unsigned int            sb_flags;       /* Proposed superblock flags (SB_*) */
 105        unsigned int            sb_flags_mask;  /* Superblock flags that were changed */
 106        unsigned int            s_iflags;       /* OR'd with sb->s_iflags */
 107        unsigned int            lsm_flags;      /* Information flags from the fs to the LSM */
 108        enum fs_context_purpose purpose:8;
 109        enum fs_context_phase   phase:8;        /* The phase the context is in */
 110        bool                    need_free:1;    /* Need to call ops->free() */
 111        bool                    global:1;       /* Goes into &init_user_ns */
 112        bool                    oldapi:1;       /* Coming from mount(2) */
 113};
 114
 115struct fs_context_operations {
 116        void (*free)(struct fs_context *fc);
 117        int (*dup)(struct fs_context *fc, struct fs_context *src_fc);
 118        int (*parse_param)(struct fs_context *fc, struct fs_parameter *param);
 119        int (*parse_monolithic)(struct fs_context *fc, void *data);
 120        int (*get_tree)(struct fs_context *fc);
 121        int (*reconfigure)(struct fs_context *fc);
 122};
 123
 124/*
 125 * fs_context manipulation functions.
 126 */
 127extern struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
 128                                                unsigned int sb_flags);
 129extern struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
 130                                                unsigned int sb_flags,
 131                                                unsigned int sb_flags_mask);
 132extern struct fs_context *fs_context_for_submount(struct file_system_type *fs_type,
 133                                                struct dentry *reference);
 134
 135extern struct fs_context *vfs_dup_fs_context(struct fs_context *fc);
 136extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param);
 137extern int vfs_parse_fs_string(struct fs_context *fc, const char *key,
 138                               const char *value, size_t v_size);
 139extern int generic_parse_monolithic(struct fs_context *fc, void *data);
 140extern int vfs_get_tree(struct fs_context *fc);
 141extern void put_fs_context(struct fs_context *fc);
 142extern int vfs_parse_fs_param_source(struct fs_context *fc,
 143                                     struct fs_parameter *param);
 144extern void fc_drop_locked(struct fs_context *fc);
 145
 146/*
 147 * sget() wrappers to be called from the ->get_tree() op.
 148 */
 149enum vfs_get_super_keying {
 150        vfs_get_single_super,   /* Only one such superblock may exist */
 151        vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */
 152        vfs_get_keyed_super,    /* Superblocks with different s_fs_info keys may exist */
 153        vfs_get_independent_super, /* Multiple independent superblocks may exist */
 154};
 155extern int vfs_get_super(struct fs_context *fc,
 156                         enum vfs_get_super_keying keying,
 157                         int (*fill_super)(struct super_block *sb,
 158                                           struct fs_context *fc));
 159
 160extern int get_tree_nodev(struct fs_context *fc,
 161                         int (*fill_super)(struct super_block *sb,
 162                                           struct fs_context *fc));
 163extern int get_tree_single(struct fs_context *fc,
 164                         int (*fill_super)(struct super_block *sb,
 165                                           struct fs_context *fc));
 166extern int get_tree_single_reconf(struct fs_context *fc,
 167                         int (*fill_super)(struct super_block *sb,
 168                                           struct fs_context *fc));
 169extern int get_tree_keyed(struct fs_context *fc,
 170                         int (*fill_super)(struct super_block *sb,
 171                                           struct fs_context *fc),
 172                         void *key);
 173
 174extern int get_tree_bdev(struct fs_context *fc,
 175                               int (*fill_super)(struct super_block *sb,
 176                                                 struct fs_context *fc));
 177
 178extern const struct file_operations fscontext_fops;
 179
 180/*
 181 * Mount error, warning and informational message logging.  This structure is
 182 * shareable between a mount and a subordinate mount.
 183 */
 184struct fc_log {
 185        refcount_t      usage;
 186        u8              head;           /* Insertion index in buffer[] */
 187        u8              tail;           /* Removal index in buffer[] */
 188        u8              need_free;      /* Mask of kfree'able items in buffer[] */
 189        struct module   *owner;         /* Owner module for strings that don't then need freeing */
 190        char            *buffer[8];
 191};
 192
 193extern __attribute__((format(printf, 4, 5)))
 194void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);
 195
 196#define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \
 197                                        l, fmt, ## __VA_ARGS__)
 198#define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \
 199                                        l, fmt, ## __VA_ARGS__)
 200/**
 201 * infof - Store supplementary informational message
 202 * @fc: The context in which to log the informational message
 203 * @fmt: The format string
 204 *
 205 * Store the supplementary informational message for the process if the process
 206 * has enabled the facility.
 207 */
 208#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)
 209#define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__)
 210#define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__)
 211
 212/**
 213 * warnf - Store supplementary warning message
 214 * @fc: The context in which to log the error message
 215 * @fmt: The format string
 216 *
 217 * Store the supplementary warning message for the process if the process has
 218 * enabled the facility.
 219 */
 220#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)
 221#define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__)
 222#define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__)
 223
 224/**
 225 * errorf - Store supplementary error message
 226 * @fc: The context in which to log the error message
 227 * @fmt: The format string
 228 *
 229 * Store the supplementary error message for the process if the process has
 230 * enabled the facility.
 231 */
 232#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)
 233#define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__)
 234#define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__)
 235
 236/**
 237 * invalf - Store supplementary invalid argument error message
 238 * @fc: The context in which to log the error message
 239 * @fmt: The format string
 240 *
 241 * Store the supplementary error message for the process if the process has
 242 * enabled the facility and return -EINVAL.
 243 */
 244#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)
 245#define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL)
 246#define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL)
 247
 248#endif /* _LINUX_FS_CONTEXT_H */
 249