Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /* Filesystem superblock creation and reconfiguration context.
0003  *
0004  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #ifndef _LINUX_FS_CONTEXT_H
0009 #define _LINUX_FS_CONTEXT_H
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/refcount.h>
0013 #include <linux/errno.h>
0014 #include <linux/security.h>
0015 #include <linux/mutex.h>
0016 
0017 struct cred;
0018 struct dentry;
0019 struct file_operations;
0020 struct file_system_type;
0021 struct mnt_namespace;
0022 struct net;
0023 struct pid_namespace;
0024 struct super_block;
0025 struct user_namespace;
0026 struct vfsmount;
0027 struct path;
0028 
0029 enum fs_context_purpose {
0030     FS_CONTEXT_FOR_MOUNT,       /* New superblock for explicit mount */
0031     FS_CONTEXT_FOR_SUBMOUNT,    /* New superblock for automatic submount */
0032     FS_CONTEXT_FOR_RECONFIGURE, /* Superblock reconfiguration (remount) */
0033 };
0034 
0035 /*
0036  * Userspace usage phase for fsopen/fspick.
0037  */
0038 enum fs_context_phase {
0039     FS_CONTEXT_CREATE_PARAMS,   /* Loading params for sb creation */
0040     FS_CONTEXT_CREATING,        /* A superblock is being created */
0041     FS_CONTEXT_AWAITING_MOUNT,  /* Superblock created, awaiting fsmount() */
0042     FS_CONTEXT_AWAITING_RECONF, /* Awaiting initialisation for reconfiguration */
0043     FS_CONTEXT_RECONF_PARAMS,   /* Loading params for reconfiguration */
0044     FS_CONTEXT_RECONFIGURING,   /* Reconfiguring the superblock */
0045     FS_CONTEXT_FAILED,      /* Failed to correctly transition a context */
0046 };
0047 
0048 /*
0049  * Type of parameter value.
0050  */
0051 enum fs_value_type {
0052     fs_value_is_undefined,
0053     fs_value_is_flag,       /* Value not given a value */
0054     fs_value_is_string,     /* Value is a string */
0055     fs_value_is_blob,       /* Value is a binary blob */
0056     fs_value_is_filename,       /* Value is a filename* + dirfd */
0057     fs_value_is_file,       /* Value is a file* */
0058 };
0059 
0060 /*
0061  * Configuration parameter.
0062  */
0063 struct fs_parameter {
0064     const char      *key;       /* Parameter name */
0065     enum fs_value_type  type:8;     /* The type of value here */
0066     union {
0067         char        *string;
0068         void        *blob;
0069         struct filename *name;
0070         struct file *file;
0071     };
0072     size_t  size;
0073     int dirfd;
0074 };
0075 
0076 struct p_log {
0077     const char *prefix;
0078     struct fc_log *log;
0079 };
0080 
0081 /*
0082  * Filesystem context for holding the parameters used in the creation or
0083  * reconfiguration of a superblock.
0084  *
0085  * Superblock creation fills in ->root whereas reconfiguration begins with this
0086  * already set.
0087  *
0088  * See Documentation/filesystems/mount_api.rst
0089  */
0090 struct fs_context {
0091     const struct fs_context_operations *ops;
0092     struct mutex        uapi_mutex; /* Userspace access mutex */
0093     struct file_system_type *fs_type;
0094     void            *fs_private;    /* The filesystem's context */
0095     void            *sget_key;
0096     struct dentry       *root;      /* The root and superblock */
0097     struct user_namespace   *user_ns;   /* The user namespace for this mount */
0098     struct net      *net_ns;    /* The network namespace for this mount */
0099     const struct cred   *cred;      /* The mounter's credentials */
0100     struct p_log        log;        /* Logging buffer */
0101     const char      *source;    /* The source name (eg. dev path) */
0102     void            *security;  /* Linux S&M options */
0103     void            *s_fs_info; /* Proposed s_fs_info */
0104     unsigned int        sb_flags;   /* Proposed superblock flags (SB_*) */
0105     unsigned int        sb_flags_mask;  /* Superblock flags that were changed */
0106     unsigned int        s_iflags;   /* OR'd with sb->s_iflags */
0107     unsigned int        lsm_flags;  /* Information flags from the fs to the LSM */
0108     enum fs_context_purpose purpose:8;
0109     enum fs_context_phase   phase:8;    /* The phase the context is in */
0110     bool            need_free:1;    /* Need to call ops->free() */
0111     bool            global:1;   /* Goes into &init_user_ns */
0112     bool            oldapi:1;   /* Coming from mount(2) */
0113 };
0114 
0115 struct fs_context_operations {
0116     void (*free)(struct fs_context *fc);
0117     int (*dup)(struct fs_context *fc, struct fs_context *src_fc);
0118     int (*parse_param)(struct fs_context *fc, struct fs_parameter *param);
0119     int (*parse_monolithic)(struct fs_context *fc, void *data);
0120     int (*get_tree)(struct fs_context *fc);
0121     int (*reconfigure)(struct fs_context *fc);
0122 };
0123 
0124 /*
0125  * fs_context manipulation functions.
0126  */
0127 extern struct fs_context *fs_context_for_mount(struct file_system_type *fs_type,
0128                         unsigned int sb_flags);
0129 extern struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
0130                         unsigned int sb_flags,
0131                         unsigned int sb_flags_mask);
0132 extern struct fs_context *fs_context_for_submount(struct file_system_type *fs_type,
0133                         struct dentry *reference);
0134 
0135 extern struct fs_context *vfs_dup_fs_context(struct fs_context *fc);
0136 extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param);
0137 extern int vfs_parse_fs_string(struct fs_context *fc, const char *key,
0138                    const char *value, size_t v_size);
0139 extern int generic_parse_monolithic(struct fs_context *fc, void *data);
0140 extern int vfs_get_tree(struct fs_context *fc);
0141 extern void put_fs_context(struct fs_context *fc);
0142 extern int vfs_parse_fs_param_source(struct fs_context *fc,
0143                      struct fs_parameter *param);
0144 extern void fc_drop_locked(struct fs_context *fc);
0145 int reconfigure_single(struct super_block *s,
0146                int flags, void *data);
0147 
0148 /*
0149  * sget() wrappers to be called from the ->get_tree() op.
0150  */
0151 enum vfs_get_super_keying {
0152     vfs_get_single_super,   /* Only one such superblock may exist */
0153     vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */
0154     vfs_get_keyed_super,    /* Superblocks with different s_fs_info keys may exist */
0155     vfs_get_independent_super, /* Multiple independent superblocks may exist */
0156 };
0157 extern int vfs_get_super(struct fs_context *fc,
0158              enum vfs_get_super_keying keying,
0159              int (*fill_super)(struct super_block *sb,
0160                        struct fs_context *fc));
0161 
0162 extern int get_tree_nodev(struct fs_context *fc,
0163              int (*fill_super)(struct super_block *sb,
0164                        struct fs_context *fc));
0165 extern int get_tree_single(struct fs_context *fc,
0166              int (*fill_super)(struct super_block *sb,
0167                        struct fs_context *fc));
0168 extern int get_tree_single_reconf(struct fs_context *fc,
0169              int (*fill_super)(struct super_block *sb,
0170                        struct fs_context *fc));
0171 extern int get_tree_keyed(struct fs_context *fc,
0172              int (*fill_super)(struct super_block *sb,
0173                        struct fs_context *fc),
0174              void *key);
0175 
0176 extern int get_tree_bdev(struct fs_context *fc,
0177                    int (*fill_super)(struct super_block *sb,
0178                          struct fs_context *fc));
0179 
0180 extern const struct file_operations fscontext_fops;
0181 
0182 /*
0183  * Mount error, warning and informational message logging.  This structure is
0184  * shareable between a mount and a subordinate mount.
0185  */
0186 struct fc_log {
0187     refcount_t  usage;
0188     u8      head;       /* Insertion index in buffer[] */
0189     u8      tail;       /* Removal index in buffer[] */
0190     u8      need_free;  /* Mask of kfree'able items in buffer[] */
0191     struct module   *owner;     /* Owner module for strings that don't then need freeing */
0192     char        *buffer[8];
0193 };
0194 
0195 extern __attribute__((format(printf, 4, 5)))
0196 void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);
0197 
0198 #define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \
0199                     l, fmt, ## __VA_ARGS__)
0200 #define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \
0201                     l, fmt, ## __VA_ARGS__)
0202 /**
0203  * infof - Store supplementary informational message
0204  * @fc: The context in which to log the informational message
0205  * @fmt: The format string
0206  *
0207  * Store the supplementary informational message for the process if the process
0208  * has enabled the facility.
0209  */
0210 #define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)
0211 #define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__)
0212 #define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__)
0213 
0214 /**
0215  * warnf - Store supplementary warning message
0216  * @fc: The context in which to log the error message
0217  * @fmt: The format string
0218  *
0219  * Store the supplementary warning message for the process if the process has
0220  * enabled the facility.
0221  */
0222 #define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)
0223 #define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__)
0224 #define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__)
0225 
0226 /**
0227  * errorf - Store supplementary error message
0228  * @fc: The context in which to log the error message
0229  * @fmt: The format string
0230  *
0231  * Store the supplementary error message for the process if the process has
0232  * enabled the facility.
0233  */
0234 #define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)
0235 #define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__)
0236 #define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__)
0237 
0238 /**
0239  * invalf - Store supplementary invalid argument error message
0240  * @fc: The context in which to log the error message
0241  * @fmt: The format string
0242  *
0243  * Store the supplementary error message for the process if the process has
0244  * enabled the facility and return -EINVAL.
0245  */
0246 #define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)
0247 #define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL)
0248 #define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL)
0249 
0250 #endif /* _LINUX_FS_CONTEXT_H */