1b4d0d230SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 29bc61ab1SDavid Howells /* Filesystem superblock creation and reconfiguration context. 39bc61ab1SDavid Howells * 49bc61ab1SDavid Howells * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 59bc61ab1SDavid Howells * Written by David Howells ([email protected]) 69bc61ab1SDavid Howells */ 79bc61ab1SDavid Howells 89bc61ab1SDavid Howells #ifndef _LINUX_FS_CONTEXT_H 99bc61ab1SDavid Howells #define _LINUX_FS_CONTEXT_H 109bc61ab1SDavid Howells 119bc61ab1SDavid Howells #include <linux/kernel.h> 12007ec26cSDavid Howells #include <linux/refcount.h> 139bc61ab1SDavid Howells #include <linux/errno.h> 149bc61ab1SDavid Howells #include <linux/security.h> 1524dcb3d9SDavid Howells #include <linux/mutex.h> 169bc61ab1SDavid Howells 179bc61ab1SDavid Howells struct cred; 189bc61ab1SDavid Howells struct dentry; 199bc61ab1SDavid Howells struct file_operations; 209bc61ab1SDavid Howells struct file_system_type; 21f3a09c92SAl Viro struct mnt_namespace; 229bc61ab1SDavid Howells struct net; 23f3a09c92SAl Viro struct pid_namespace; 24f3a09c92SAl Viro struct super_block; 259bc61ab1SDavid Howells struct user_namespace; 26f3a09c92SAl Viro struct vfsmount; 27f3a09c92SAl Viro struct path; 289bc61ab1SDavid Howells 299bc61ab1SDavid Howells enum fs_context_purpose { 309bc61ab1SDavid Howells FS_CONTEXT_FOR_MOUNT, /* New superblock for explicit mount */ 31e1a91586SAl Viro FS_CONTEXT_FOR_SUBMOUNT, /* New superblock for automatic submount */ 328d0347f6SDavid Howells FS_CONTEXT_FOR_RECONFIGURE, /* Superblock reconfiguration (remount) */ 339bc61ab1SDavid Howells }; 349bc61ab1SDavid Howells 359bc61ab1SDavid Howells /* 3624dcb3d9SDavid Howells * Userspace usage phase for fsopen/fspick. 3724dcb3d9SDavid Howells */ 3824dcb3d9SDavid Howells enum fs_context_phase { 3924dcb3d9SDavid Howells FS_CONTEXT_CREATE_PARAMS, /* Loading params for sb creation */ 4024dcb3d9SDavid Howells FS_CONTEXT_CREATING, /* A superblock is being created */ 4124dcb3d9SDavid Howells FS_CONTEXT_AWAITING_MOUNT, /* Superblock created, awaiting fsmount() */ 4224dcb3d9SDavid Howells FS_CONTEXT_AWAITING_RECONF, /* Awaiting initialisation for reconfiguration */ 4324dcb3d9SDavid Howells FS_CONTEXT_RECONF_PARAMS, /* Loading params for reconfiguration */ 4424dcb3d9SDavid Howells FS_CONTEXT_RECONFIGURING, /* Reconfiguring the superblock */ 4524dcb3d9SDavid Howells FS_CONTEXT_FAILED, /* Failed to correctly transition a context */ 4624dcb3d9SDavid Howells }; 4724dcb3d9SDavid Howells 4824dcb3d9SDavid Howells /* 4931d921c7SDavid Howells * Type of parameter value. 5031d921c7SDavid Howells */ 5131d921c7SDavid Howells enum fs_value_type { 5231d921c7SDavid Howells fs_value_is_undefined, 5331d921c7SDavid Howells fs_value_is_flag, /* Value not given a value */ 5431d921c7SDavid Howells fs_value_is_string, /* Value is a string */ 5531d921c7SDavid Howells fs_value_is_blob, /* Value is a binary blob */ 5631d921c7SDavid Howells fs_value_is_filename, /* Value is a filename* + dirfd */ 5731d921c7SDavid Howells fs_value_is_file, /* Value is a file* */ 5831d921c7SDavid Howells }; 5931d921c7SDavid Howells 6031d921c7SDavid Howells /* 6131d921c7SDavid Howells * Configuration parameter. 6231d921c7SDavid Howells */ 6331d921c7SDavid Howells struct fs_parameter { 6431d921c7SDavid Howells const char *key; /* Parameter name */ 6531d921c7SDavid Howells enum fs_value_type type:8; /* The type of value here */ 6631d921c7SDavid Howells union { 6731d921c7SDavid Howells char *string; 6831d921c7SDavid Howells void *blob; 6931d921c7SDavid Howells struct filename *name; 7031d921c7SDavid Howells struct file *file; 7131d921c7SDavid Howells }; 7231d921c7SDavid Howells size_t size; 7331d921c7SDavid Howells int dirfd; 7431d921c7SDavid Howells }; 7531d921c7SDavid Howells 763fbb8d55SAl Viro struct p_log { 773fbb8d55SAl Viro const char *prefix; 783fbb8d55SAl Viro struct fc_log *log; 793fbb8d55SAl Viro }; 803fbb8d55SAl Viro 8131d921c7SDavid Howells /* 829bc61ab1SDavid Howells * Filesystem context for holding the parameters used in the creation or 839bc61ab1SDavid Howells * reconfiguration of a superblock. 849bc61ab1SDavid Howells * 859bc61ab1SDavid Howells * Superblock creation fills in ->root whereas reconfiguration begins with this 869bc61ab1SDavid Howells * already set. 879bc61ab1SDavid Howells * 88791a17eeSMauro Carvalho Chehab * See Documentation/filesystems/mount_api.rst 899bc61ab1SDavid Howells */ 909bc61ab1SDavid Howells struct fs_context { 91f3a09c92SAl Viro const struct fs_context_operations *ops; 9224dcb3d9SDavid Howells struct mutex uapi_mutex; /* Userspace access mutex */ 939bc61ab1SDavid Howells struct file_system_type *fs_type; 949bc61ab1SDavid Howells void *fs_private; /* The filesystem's context */ 95fe62c3a4SDavid Howells void *sget_key; 969bc61ab1SDavid Howells struct dentry *root; /* The root and superblock */ 979bc61ab1SDavid Howells struct user_namespace *user_ns; /* The user namespace for this mount */ 989bc61ab1SDavid Howells struct net *net_ns; /* The network namespace for this mount */ 999bc61ab1SDavid Howells const struct cred *cred; /* The mounter's credentials */ 100cc3c0b53SAl Viro struct p_log log; /* Logging buffer */ 1019bc61ab1SDavid Howells const char *source; /* The source name (eg. dev path) */ 1023b87d9f4SPaul Moore void *security; /* LSM options */ 103cb50b348SAl Viro void *s_fs_info; /* Proposed s_fs_info */ 1049bc61ab1SDavid Howells unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ 1059bc61ab1SDavid Howells unsigned int sb_flags_mask; /* Superblock flags that were changed */ 106c80fa7c8SDavid Howells unsigned int s_iflags; /* OR'd with sb->s_iflags */ 1079bc61ab1SDavid Howells enum fs_context_purpose purpose:8; 10824dcb3d9SDavid Howells enum fs_context_phase phase:8; /* The phase the context is in */ 1099bc61ab1SDavid Howells bool need_free:1; /* Need to call ops->free() */ 110cb50b348SAl Viro bool global:1; /* Goes into &init_user_ns */ 111b330966fSMiklos Szeredi bool oldapi:1; /* Coming from mount(2) */ 11222ed7ecdSChristian Brauner bool exclusive:1; /* create new superblock, reject existing one */ 1139bc61ab1SDavid Howells }; 1149bc61ab1SDavid Howells 115f3a09c92SAl Viro struct fs_context_operations { 116f3a09c92SAl Viro void (*free)(struct fs_context *fc); 1170b52075eSAl Viro int (*dup)(struct fs_context *fc, struct fs_context *src_fc); 1183e1aeb00SDavid Howells int (*parse_param)(struct fs_context *fc, struct fs_parameter *param); 119f3a09c92SAl Viro int (*parse_monolithic)(struct fs_context *fc, void *data); 120f3a09c92SAl Viro int (*get_tree)(struct fs_context *fc); 121f3a09c92SAl Viro int (*reconfigure)(struct fs_context *fc); 122f3a09c92SAl Viro }; 123f3a09c92SAl Viro 1249bc61ab1SDavid Howells /* 1259bc61ab1SDavid Howells * fs_context manipulation functions. 1269bc61ab1SDavid Howells */ 1279bc61ab1SDavid Howells extern struct fs_context *fs_context_for_mount(struct file_system_type *fs_type, 1289bc61ab1SDavid Howells unsigned int sb_flags); 1298d0347f6SDavid Howells extern struct fs_context *fs_context_for_reconfigure(struct dentry *dentry, 1308d0347f6SDavid Howells unsigned int sb_flags, 1318d0347f6SDavid Howells unsigned int sb_flags_mask); 132e1a91586SAl Viro extern struct fs_context *fs_context_for_submount(struct file_system_type *fs_type, 133e1a91586SAl Viro struct dentry *reference); 1349bc61ab1SDavid Howells 1350b52075eSAl Viro extern struct fs_context *vfs_dup_fs_context(struct fs_context *fc); 1363e1aeb00SDavid Howells extern int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param); 1373e1aeb00SDavid Howells extern int vfs_parse_fs_string(struct fs_context *fc, const char *key, 1383e1aeb00SDavid Howells const char *value, size_t v_size); 139e001d144SAmir Goldstein int vfs_parse_monolithic_sep(struct fs_context *fc, void *data, 140e001d144SAmir Goldstein char *(*sep)(char **)); 1413e1aeb00SDavid Howells extern int generic_parse_monolithic(struct fs_context *fc, void *data); 1429bc61ab1SDavid Howells extern int vfs_get_tree(struct fs_context *fc); 1439bc61ab1SDavid Howells extern void put_fs_context(struct fs_context *fc); 144d1d488d8SChristian Brauner extern int vfs_parse_fs_param_source(struct fs_context *fc, 145d1d488d8SChristian Brauner struct fs_parameter *param); 1461e7107c5SPaul Gortmaker extern void fc_drop_locked(struct fs_context *fc); 1479bc61ab1SDavid Howells 1482ac295d4SAl Viro extern int get_tree_nodev(struct fs_context *fc, 1492ac295d4SAl Viro int (*fill_super)(struct super_block *sb, 1502ac295d4SAl Viro struct fs_context *fc)); 151c23a0bbaSAl Viro extern int get_tree_single(struct fs_context *fc, 152c23a0bbaSAl Viro int (*fill_super)(struct super_block *sb, 153c23a0bbaSAl Viro struct fs_context *fc)); 154533770ccSAl Viro extern int get_tree_keyed(struct fs_context *fc, 155533770ccSAl Viro int (*fill_super)(struct super_block *sb, 156533770ccSAl Viro struct fs_context *fc), 157533770ccSAl Viro void *key); 158cb50b348SAl Viro 159cf6da236SChristoph Hellwig int setup_bdev_super(struct super_block *sb, int sb_flags, 160cf6da236SChristoph Hellwig struct fs_context *fc); 161*4021e685SGao Xiang 162*4021e685SGao Xiang #define GET_TREE_BDEV_QUIET_LOOKUP 0x0001 163*4021e685SGao Xiang int get_tree_bdev_flags(struct fs_context *fc, 164*4021e685SGao Xiang int (*fill_super)(struct super_block *sb, 165*4021e685SGao Xiang struct fs_context *fc), unsigned int flags); 166*4021e685SGao Xiang 167fe62c3a4SDavid Howells extern int get_tree_bdev(struct fs_context *fc, 168fe62c3a4SDavid Howells int (*fill_super)(struct super_block *sb, 169fe62c3a4SDavid Howells struct fs_context *fc)); 170fe62c3a4SDavid Howells 171e7582e16SDavid Howells extern const struct file_operations fscontext_fops; 172e7582e16SDavid Howells 173007ec26cSDavid Howells /* 174007ec26cSDavid Howells * Mount error, warning and informational message logging. This structure is 175007ec26cSDavid Howells * shareable between a mount and a subordinate mount. 176007ec26cSDavid Howells */ 177007ec26cSDavid Howells struct fc_log { 178007ec26cSDavid Howells refcount_t usage; 179007ec26cSDavid Howells u8 head; /* Insertion index in buffer[] */ 180007ec26cSDavid Howells u8 tail; /* Removal index in buffer[] */ 181007ec26cSDavid Howells u8 need_free; /* Mask of kfree'able items in buffer[] */ 182007ec26cSDavid Howells struct module *owner; /* Owner module for strings that don't then need freeing */ 183007ec26cSDavid Howells char *buffer[8]; 184007ec26cSDavid Howells }; 185007ec26cSDavid Howells 1869f09f649SAl Viro extern __attribute__((format(printf, 4, 5))) 1879f09f649SAl Viro void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...); 188c6b82263SDavid Howells 189cc3c0b53SAl Viro #define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \ 1907f5d3814SAl Viro l, fmt, ## __VA_ARGS__) 1913fbb8d55SAl Viro #define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \ 1923fbb8d55SAl Viro l, fmt, ## __VA_ARGS__) 193c6b82263SDavid Howells /** 194c6b82263SDavid Howells * infof - Store supplementary informational message 195c6b82263SDavid Howells * @fc: The context in which to log the informational message 196c6b82263SDavid Howells * @fmt: The format string 197c6b82263SDavid Howells * 198c6b82263SDavid Howells * Store the supplementary informational message for the process if the process 199c6b82263SDavid Howells * has enabled the facility. 200c6b82263SDavid Howells */ 2019f09f649SAl Viro #define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__) 2023fbb8d55SAl Viro #define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__) 203a3ff937bSAl Viro #define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__) 204c6b82263SDavid Howells 205c6b82263SDavid Howells /** 206c6b82263SDavid Howells * warnf - Store supplementary warning message 207c6b82263SDavid Howells * @fc: The context in which to log the error message 208c6b82263SDavid Howells * @fmt: The format string 209c6b82263SDavid Howells * 210c6b82263SDavid Howells * Store the supplementary warning message for the process if the process has 211c6b82263SDavid Howells * enabled the facility. 212c6b82263SDavid Howells */ 2139f09f649SAl Viro #define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__) 2143fbb8d55SAl Viro #define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__) 215a3ff937bSAl Viro #define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__) 216c6b82263SDavid Howells 217c6b82263SDavid Howells /** 218c6b82263SDavid Howells * errorf - Store supplementary error message 219c6b82263SDavid Howells * @fc: The context in which to log the error message 220c6b82263SDavid Howells * @fmt: The format string 221c6b82263SDavid Howells * 222c6b82263SDavid Howells * Store the supplementary error message for the process if the process has 223c6b82263SDavid Howells * enabled the facility. 224c6b82263SDavid Howells */ 2259f09f649SAl Viro #define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__) 2263fbb8d55SAl Viro #define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__) 227a3ff937bSAl Viro #define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__) 228c6b82263SDavid Howells 229c6b82263SDavid Howells /** 230c6b82263SDavid Howells * invalf - Store supplementary invalid argument error message 231c6b82263SDavid Howells * @fc: The context in which to log the error message 232c6b82263SDavid Howells * @fmt: The format string 233c6b82263SDavid Howells * 234c6b82263SDavid Howells * Store the supplementary error message for the process if the process has 235c6b82263SDavid Howells * enabled the facility and return -EINVAL. 236c6b82263SDavid Howells */ 2379f09f649SAl Viro #define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL) 2383fbb8d55SAl Viro #define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL) 239a3ff937bSAl Viro #define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL) 240c6b82263SDavid Howells 2419bc61ab1SDavid Howells #endif /* _LINUX_FS_CONTEXT_H */ 242