linux/fs/nfsd/export.c

// SPDX-License-Identifier: GPL-2.0
/*
 * NFS exporting and validation.
 *
 * We maintain a list of clients, each of which has a list of
 * exports. To export an fs to a given client, you first have
 * to create the client entry with NFSCTL_ADDCLIENT, which
 * creates a client control block and adds it to the hash
 * table. Then, you call NFSCTL_EXPORT for each fs.
 *
 *
 * Copyright (C) 1995, 1996 Olaf Kirch, <[email protected]>
 */

#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/exportfs.h>
#include <linux/sunrpc/svc_xprt.h>

#include "nfsd.h"
#include "nfsfh.h"
#include "netns.h"
#include "pnfs.h"
#include "filecache.h"
#include "trace.h"

#define NFSDDBG_FACILITY

/*
 * We have two caches.
 * One maps client+vfsmnt+dentry to export options - the export map
 * The other maps client+filehandle-fragment to export options. - the expkey map
 *
 * The export options are actually stored in the first map, and the
 * second map contains a reference to the entry in the first map.
 */

#define EXPKEY_HASHBITS
#define EXPKEY_HASHMAX
#define EXPKEY_HASHMASK

static void expkey_put(struct kref *ref)
{}

static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
{}

static void expkey_request(struct cache_detail *cd,
			   struct cache_head *h,
			   char **bpp, int *blen)
{}

static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
					    struct svc_expkey *old);
static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *);

static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
{}

static int expkey_show(struct seq_file *m,
		       struct cache_detail *cd,
		       struct cache_head *h)
{}

static inline int expkey_match (struct cache_head *a, struct cache_head *b)
{}

static inline void expkey_init(struct cache_head *cnew,
				   struct cache_head *citem)
{}

static inline void expkey_update(struct cache_head *cnew,
				   struct cache_head *citem)
{}

static struct cache_head *expkey_alloc(void)
{}

static void expkey_flush(void)
{}

static const struct cache_detail svc_expkey_cache_template =;

static int
svc_expkey_hash(struct svc_expkey *item)
{}

static struct svc_expkey *
svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
{}

static struct svc_expkey *
svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
		  struct svc_expkey *old)
{}


#define EXPORT_HASHBITS
#define EXPORT_HASHMAX

static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
{}

static int export_stats_init(struct export_stats *stats)
{}

static void export_stats_reset(struct export_stats *stats)
{}

static void export_stats_destroy(struct export_stats *stats)
{}

static void svc_export_put(struct kref *ref)
{}

static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
{}

static void svc_export_request(struct cache_detail *cd,
			       struct cache_head *h,
			       char **bpp, int *blen)
{}

static struct svc_export *svc_export_update(struct svc_export *new,
					    struct svc_export *old);
static struct svc_export *svc_export_lookup(struct svc_export *);

static int check_export(struct path *path, int *flags, unsigned char *uuid)
{}

#ifdef CONFIG_NFSD_V4

static int
fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
{}

static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
{}

#else /* CONFIG_NFSD_V4 */
static inline int
fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc){return 0;}
static inline int
secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
#endif

static int xprtsec_parse(char **mesg, char *buf, struct svc_export *exp)
{}

static inline int
nfsd_uuid_parse(char **mesg, char *buf, unsigned char **puuid)
{}

static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
{}

static void exp_flags(struct seq_file *m, int flag, int fsid,
		kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);
static void show_secinfo(struct seq_file *m, struct svc_export *exp);

static int is_export_stats_file(struct seq_file *m)
{}

static int svc_export_show(struct seq_file *m,
			   struct cache_detail *cd,
			   struct cache_head *h)
{}
static int svc_export_match(struct cache_head *a, struct cache_head *b)
{}

static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
{}

static void export_update(struct cache_head *cnew, struct cache_head *citem)
{}

static struct cache_head *svc_export_alloc(void)
{}

static const struct cache_detail svc_export_cache_template =;

static int
svc_export_hash(struct svc_export *exp)
{}

static struct svc_export *
svc_export_lookup(struct svc_export *exp)
{}

static struct svc_export *
svc_export_update(struct svc_export *new, struct svc_export *old)
{}


static struct svc_expkey *
exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
	     u32 *fsidv, struct cache_req *reqp)
{}

static struct svc_export *
exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
		const struct path *path, struct cache_req *reqp)
{}

/*
 * Find the export entry for a given dentry.
 */
static struct svc_export *
exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
{}



/*
 * Obtain the root fh on behalf of a client.
 * This could be done in user space, but I feel that it adds some safety
 * since its harder to fool a kernel module than a user space program.
 */
int
exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
	   struct knfsd_fh *f, int maxsize)
{}

static struct svc_export *exp_find(struct cache_detail *cd,
				   struct auth_domain *clp, int fsid_type,
				   u32 *fsidv, struct cache_req *reqp)
{}

__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
{}

/*
 * Uses rq_client and rq_gssclient to find an export; uses rq_client (an
 * auth_unix client) if it's available and has secinfo information;
 * otherwise, will try to use rq_gssclient.
 *
 * Called from functions that handle requests; functions that do work on
 * behalf of mountd are passed a single client name to use, and should
 * use exp_get_by_name() or exp_find().
 */
struct svc_export *
rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
{}

struct svc_export *
rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
{}

struct svc_export *
rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
{}

struct svc_export *rqst_find_fsidzero_export(struct svc_rqst *rqstp)
{}

/*
 * Called when we need the filehandle for the root of the pseudofs,
 * for a given NFSv4 client.   The root is defined to be the
 * export point with fsid==0
 */
__be32
exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
{}

static struct flags {} expflags[] =;

static void show_expflags(struct seq_file *m, int flags, int mask)
{}

static void show_secinfo_flags(struct seq_file *m, int flags)
{}

static bool secinfo_flags_equal(int f, int g)
{}

static int show_secinfo_run(struct seq_file *m, struct exp_flavor_info **fp, struct exp_flavor_info *end)
{}

static void show_secinfo(struct seq_file *m, struct svc_export *exp)
{}

static void exp_flags(struct seq_file *m, int flag, int fsid,
		kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
{}

static int e_show(struct seq_file *m, void *p)
{}

const struct seq_operations nfs_exports_op =;

/*
 * Initialize the exports module.
 */
int
nfsd_export_init(struct net *net)
{}

/*
 * Flush exports table - called when last nfsd thread is killed
 */
void
nfsd_export_flush(struct net *net)
{}

/*
 * Shutdown the exports module.
 */
void
nfsd_export_shutdown(struct net *net)
{}