14 #include <linux/slab.h>
16 #include <linux/module.h>
26 #define NFSDDBG_FACILITY NFSDDBG_EXPORT
40 #define EXPKEY_HASHBITS 8
41 #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
42 #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
44 static void expkey_put(
struct kref *ref)
57 char **
bpp,
int *blen)
79 static int expkey_parse(
struct cache_detail *cd,
char *mesg,
int mlen)
84 struct auth_domain *dom =
NULL;
91 if (mesg[mlen - 1] !=
'\n')
108 dprintk(
"found domain %s\n", buf);
116 dprintk(
"found fsidtype %d\n", fsidtype);
121 dprintk(
"found fsid length %d\n", len);
127 key.h.expiry_time = get_expiry(&mesg);
128 if (
key.h.expiry_time == 0)
132 key.ek_fsidtype = fsidtype;
135 ek = svc_expkey_lookup(cd, &
key);
145 dprintk(
"Path seems to be <%s>\n", buf);
149 ek = svc_expkey_update(cd, &
key, ek);
157 dprintk(
"Found the path %s\n", buf);
159 ek = svc_expkey_update(cd, &
key, ek);
167 cache_put(&ek->
h, cd);
174 static int expkey_show(
struct seq_file *
m,
182 seq_puts(m,
"#domain fsidtype fsid [path]\n");
211 static inline void expkey_init(
struct cache_head *cnew,
224 static inline void expkey_update(
struct cache_head *cnew,
243 static struct cache_detail svc_expkey_cache_template = {
247 .cache_put = expkey_put,
248 .cache_upcall = expkey_upcall,
249 .cache_parse = expkey_parse,
250 .cache_show = expkey_show,
251 .match = expkey_match,
253 .update = expkey_update,
254 .alloc = expkey_alloc,
274 int hash = svc_expkey_hash(item);
288 int hash = svc_expkey_hash(
new);
298 #define EXPORT_HASHBITS 8
299 #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
312 static void svc_export_put(
struct kref *
ref)
323 char **bpp,
int *blen)
378 dprintk(
"exp_export: export of non-dev fs without fsid\n");
382 if (!inode->
i_sb->s_export_op ||
383 !inode->
i_sb->s_export_op->fh_to_dentry) {
384 dprintk(
"exp_export: export of invalid fs type.\n");
392 #ifdef CONFIG_NFSD_V4
398 int migrated,
i,
err;
434 err = get_int(mesg, &migrated);
438 if (migrated < 0 || migrated > 1)
443 nfsd4_fslocs_free(fsloc);
447 static int secinfo_parse(
char **mesg,
char *buf,
struct svc_export *exp)
452 err = get_int(mesg, &listsize);
458 for (f = exp->
ex_flavors; f < exp->ex_flavors + listsize; f++) {
468 err = get_uint(mesg, &f->
flags);
483 secinfo_parse(
char **mesg,
char *buf,
struct svc_export *exp) {
return 0; }
486 static int svc_export_parse(
struct cache_detail *cd,
char *mesg,
int mlen)
492 struct auth_domain *dom =
NULL;
496 if (mesg[mlen-1] !=
'\n')
529 exp.
h.expiry_time = get_expiry(&mesg);
530 if (exp.
h.expiry_time == 0)
534 err = get_int(&mesg, &an_int);
539 if (err || an_int < 0)
544 err = get_int(&mesg, &an_int);
550 err = get_int(&mesg, &an_int);
556 err = get_int(&mesg, &an_int);
562 if (
strcmp(buf,
"fsloc") == 0)
563 err = fsloc_parse(&mesg, buf, &exp.
ex_fslocs);
564 else if (
strcmp(buf,
"uuid") == 0) {
575 }
else if (
strcmp(buf,
"secinfo") == 0)
576 err = secinfo_parse(&mesg, buf, &exp);
593 expp = svc_export_lookup(&exp);
595 expp = svc_export_update(&exp, expp);
619 static int svc_export_show(
struct seq_file *m,
626 seq_puts(m,
"#path domain(flags)\n");
641 for (i=0; i<16; i++) {
647 show_secinfo(m, exp);
656 return orig->
ex_client ==
new->ex_client &&
657 orig->
ex_path.dentry ==
new->ex_path.dentry &&
658 orig->
ex_path.mnt ==
new->ex_path.mnt;
668 new->ex_path.dentry = dget(item->
ex_path.dentry);
670 new->ex_fslocs.locations =
NULL;
671 new->ex_fslocs.locations_count = 0;
672 new->ex_fslocs.migrated = 0;
688 new->ex_fslocs.locations = item->
ex_fslocs.locations;
690 new->ex_fslocs.locations_count = item->
ex_fslocs.locations_count;
692 new->ex_fslocs.migrated = item->
ex_fslocs.migrated;
700 static struct cache_head *svc_export_alloc(
void)
709 static struct cache_detail svc_export_cache_template = {
712 .name =
"nfsd.export",
713 .cache_put = svc_export_put,
714 .cache_upcall = svc_export_upcall,
715 .cache_parse = svc_export_parse,
716 .cache_show = svc_export_show,
717 .match = svc_export_match,
718 .init = svc_export_init,
719 .update = export_update,
720 .alloc = svc_export_alloc,
738 int hash = svc_export_hash(exp);
751 int hash = svc_export_hash(old);
772 key.ek_fsidtype = fsid_type;
775 ek = svc_expkey_lookup(cd, &
key);
798 exp = svc_export_lookup(&key);
820 exp = exp_get_by_name(cd, clp, path,
NULL);
849 printk(
"nfsd: exp_rootfh path not found %s", name);
852 inode = path.
dentry->d_inode;
854 dprintk(
"nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
855 name, path.
dentry, clp->name,
857 exp = exp_parent(cd, clp, &path);
866 fh_init(&fh, maxsize);
880 struct auth_domain *clp,
int fsid_type,
889 exp = exp_get_by_name(cd, clp, &ek->
ek_path, reqp);
893 return ERR_CAST(exp);
912 if (rqstp->
rq_cred.cr_flavor == RPC_AUTH_NULL ||
913 rqstp->
rq_cred.cr_flavor == RPC_AUTH_UNIX)
940 if (PTR_ERR(exp) == -
ENOENT)
952 if (PTR_ERR(gssexp) == -
ENOENT)
970 exp = exp_find(cd, rqstp->
rq_client, fsid_type,
972 if (PTR_ERR(exp) == -
ENOENT)
983 gssexp = exp_find(cd, rqstp->
rq_gssclient, fsid_type, fsidv,
985 if (PTR_ERR(gssexp) == -
ENOENT)
1039 static void *e_start(
struct seq_file *m, loff_t *
pos)
1052 export = n & ((1
LL<<32) - 1);
1055 for (ch=export_table[hash]; ch; ch=ch->
next)
1058 n &= ~((1
LL<<32) - 1);
1066 return export_table[
hash];
1069 static void *e_next(
struct seq_file *m,
void *
p, loff_t *
pos)
1072 int hash = (*pos >> 32);
1085 *pos &= ~((1
LL<<32) - 1);
1093 return export_table[
hash];
1096 static void e_stop(
struct seq_file *m,
void *p)
1104 static struct flags {
1122 static void show_expflags(
struct seq_file *m,
int flags,
int mask)
1127 for (flg = expflags; flg->flag; flg++) {
1128 if (flg->flag & ~mask)
1130 state = (flg->flag &
flags) ? 0 : 1;
1131 if (*flg->name[state])
1132 seq_printf(m,
"%s%s", first++?
",":
"", flg->name[state]);
1136 static void show_secinfo_flags(
struct seq_file *m,
int flags)
1142 static bool secinfo_flags_equal(
int f,
int g)
1153 flags = (*fp)->flags;
1154 seq_printf(m,
",sec=%d", (*fp)->pseudoflavor);
1156 while (*fp != end && secinfo_flags_equal(flags, (*fp)->flags)) {
1172 flags = show_secinfo_run(m, &f, end);
1173 if (!secinfo_flags_equal(flags, exp->
ex_flags))
1174 show_secinfo_flags(m, flags);
1176 flags = show_secinfo_run(m, &f, end);
1177 show_secinfo_flags(m, flags);
1185 if (flag & NFSEXP_FSID)
1187 if (anonu != (
uid_t)-2 && anonu != (0x10000-2))
1189 if (anong != (
gid_t)-2 && anong != (0x10000-2))
1192 char *loctype = (fsloc->
migrated) ?
"refer" :
"replicas";
1208 static int e_show(
struct seq_file *m,
void *p)
1216 seq_puts(m,
"# Path Client(Flags) # IPs\n");
1224 return svc_export_show(m, cd, cp);
1243 dprintk(
"nfsd: initializing export module (net: %p).\n", net);
1250 goto destroy_export_cache;
1255 goto unregister_export_cache;
1259 goto destroy_expkey_cache;
1262 destroy_expkey_cache:
1264 unregister_export_cache:
1266 destroy_export_cache:
1291 dprintk(
"nfsd: shutting down export module (net: %p).\n", net);
1299 dprintk(
"nfsd: export shutdown complete (net: %p).\n", net);