From f2aedb713c284429987dc66c7aaf38decfc8da2a Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 10 Dec 2019 07:31:13 -0500 Subject: NFS: Add fs_context support. Add filesystem context support to NFS, parsing the options in advance and attaching the information to struct nfs_fs_context. The highlights are: (*) Merge nfs_mount_info and nfs_clone_mount into nfs_fs_context. This structure represents NFS's superblock config. (*) Make use of the VFS's parsing support to split comma-separated lists (*) Pin the NFS protocol module in the nfs_fs_context. (*) Attach supplementary error information to fs_context. This has the downside that these strings must be static and can't be formatted. (*) Remove the auxiliary file_system_type structs since the information necessary can be conveyed in the nfs_fs_context struct instead. (*) Root mounts are made by duplicating the config for the requested mount so as to have the same parameters. Submounts pick up their parameters from the parent superblock. [AV -- retrans is u32, not string] [SM -- Renamed cfg to ctx in a few functions in an earlier patch] [SM -- Moved fs_context mount option parsing to an earlier patch] [SM -- Moved fs_context error logging to a later patch] [SM -- Fixed printks in nfs4_try_get_tree() and nfs4_get_referral_tree()] [SM -- Added is_remount_fc() helper] [SM -- Deferred some refactoring to a later patch] [SM -- Fixed referral mounts, which were broken in the original patch] [SM -- Fixed leak of nfs_fattr when fs_context is freed] Signed-off-by: David Howells Signed-off-by: Al Viro Signed-off-by: Scott Mayhew Signed-off-by: Anna Schumaker --- fs/nfs/internal.h | 74 +++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 41 deletions(-) (limited to 'fs/nfs/internal.h') diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 003c2b8eb1e6..1cd09df9e0b5 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -4,7 +4,7 @@ */ #include "nfs4_fs.h" -#include +#include #include #include #include @@ -16,6 +16,7 @@ extern const struct export_operations nfs_export_ops; struct nfs_string; +struct nfs_pageio_descriptor; static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr) { @@ -34,12 +35,13 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) struct nfs_clone_mount { const struct super_block *sb; - const struct dentry *dentry; + struct dentry *dentry; char *hostname; char *mnt_path; struct sockaddr *addr; size_t addrlen; rpc_authflavor_t authflavor; + struct nfs_fattr *fattr; }; /* @@ -78,10 +80,23 @@ struct nfs_client_initdata { const struct cred *cred; }; +struct nfs_mount_info { + unsigned int inherited_bsize; + struct nfs_fs_context *ctx; + struct nfs_clone_mount *cloned; + struct nfs_server *server; + struct nfs_fh *mntfh; + struct nfs_subversion *nfs_mod; +}; + /* * In-kernel mount arguments */ struct nfs_fs_context { + bool internal; + bool skip_reconfig_option_check; + bool need_mount; + bool sloppy; unsigned int flags; /* NFS{,4}_MOUNT_* flags */ unsigned int rsize, wsize; unsigned int timeo, retrans; @@ -98,8 +113,6 @@ struct nfs_fs_context { char *fscache_uniq; unsigned short protofamily; unsigned short mountfamily; - bool need_mount; - bool sloppy; struct { union { @@ -124,14 +137,23 @@ struct nfs_fs_context { int port; unsigned short protocol; unsigned short nconnect; + unsigned short export_path_len; } nfs_server; void *lsm_opts; struct net *net; char buf[32]; /* Parse buffer */ + + struct nfs_mount_info mount_info; + struct nfs_clone_mount clone_data; }; +static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc) +{ + return fc->fs_private; +} + /* mount_clnt.c */ struct nfs_mount_request { struct sockaddr *sap; @@ -147,15 +169,6 @@ struct nfs_mount_request { struct net *net; }; -struct nfs_mount_info { - unsigned int inherited_bsize; - struct nfs_fs_context *ctx; - struct nfs_clone_mount *cloned; - struct nfs_server *server; - struct nfs_fh *mntfh; - struct nfs_subversion *nfs_mod; -}; - extern int nfs_mount(struct nfs_mount_request *info); extern void nfs_umount(const struct nfs_mount_request *info); @@ -235,22 +248,8 @@ static inline void nfs_fs_proc_exit(void) extern const struct svc_version nfs4_callback_version1; extern const struct svc_version nfs4_callback_version4; -struct nfs_pageio_descriptor; - -/* mount.c */ -#define NFS_TEXT_DATA 1 - -extern struct nfs_fs_context *nfs_alloc_parsed_mount_data(void); -extern void nfs_free_parsed_mount_data(struct nfs_fs_context *ctx); -extern int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx); -extern int nfs_validate_mount_data(struct file_system_type *fs_type, - void *options, - struct nfs_fs_context *ctx, - struct nfs_fh *mntfh, - const char *dev_name); -extern int nfs_validate_text_mount_data(void *options, - struct nfs_fs_context *ctx, - const char *dev_name); +/* fs_context.c */ +extern struct file_system_type nfs_fs_type; /* pagelist.c */ extern int __init nfs_init_nfspagecache(void); @@ -411,14 +410,9 @@ extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode); /* super.c */ extern const struct super_operations nfs_sops; -extern struct file_system_type nfs_fs_type; -extern struct file_system_type nfs_prepared_fs_type; -#if IS_ENABLED(CONFIG_NFS_V4) -extern struct file_system_type nfs4_referral_fs_type; -#endif bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t); -struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *); -struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); +int nfs_try_get_tree(struct fs_context *); +int nfs_get_tree_common(struct fs_context *); void nfs_kill_super(struct super_block *); extern struct rpc_stat nfs_rpcstat; @@ -446,10 +440,8 @@ static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi) extern char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, unsigned flags); extern struct vfsmount *nfs_d_automount(struct path *path); -struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, - struct nfs_fh *, struct nfs_fattr *); -struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *, - struct nfs_fattr *, rpc_authflavor_t); +int nfs_submount(struct fs_context *, struct nfs_server *); +int nfs_do_submount(struct fs_context *); /* getroot.c */ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, @@ -476,7 +468,7 @@ int nfs_show_options(struct seq_file *, struct dentry *); int nfs_show_devname(struct seq_file *, struct dentry *); int nfs_show_path(struct seq_file *, struct dentry *); int nfs_show_stats(struct seq_file *, struct dentry *); -int nfs_remount(struct super_block *sb, int *flags, char *raw_data); +int nfs_reconfigure(struct fs_context *); /* write.c */ extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, -- cgit v1.2.3