diff options
Diffstat (limited to 'fs/nfsd/export.c')
-rw-r--r-- | fs/nfsd/export.c | 125 |
1 files changed, 58 insertions, 67 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 5cd882b8871a..5839b229cd0e 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -163,18 +163,16 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
163 | if (!ek) | 163 | if (!ek) |
164 | err = -ENOMEM; | 164 | err = -ENOMEM; |
165 | } else { | 165 | } else { |
166 | struct nameidata nd; | 166 | err = kern_path(buf, 0, &key.ek_path); |
167 | err = path_lookup(buf, 0, &nd); | ||
168 | if (err) | 167 | if (err) |
169 | goto out; | 168 | goto out; |
170 | 169 | ||
171 | dprintk("Found the path %s\n", buf); | 170 | dprintk("Found the path %s\n", buf); |
172 | key.ek_path = nd.path; | ||
173 | 171 | ||
174 | ek = svc_expkey_update(&key, ek); | 172 | ek = svc_expkey_update(&key, ek); |
175 | if (!ek) | 173 | if (!ek) |
176 | err = -ENOMEM; | 174 | err = -ENOMEM; |
177 | path_put(&nd.path); | 175 | path_put(&key.ek_path); |
178 | } | 176 | } |
179 | cache_flush(); | 177 | cache_flush(); |
180 | out: | 178 | out: |
@@ -501,35 +499,22 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
501 | int len; | 499 | int len; |
502 | int err; | 500 | int err; |
503 | struct auth_domain *dom = NULL; | 501 | struct auth_domain *dom = NULL; |
504 | struct nameidata nd; | 502 | struct svc_export exp = {}, *expp; |
505 | struct svc_export exp, *expp; | ||
506 | int an_int; | 503 | int an_int; |
507 | 504 | ||
508 | nd.path.dentry = NULL; | ||
509 | exp.ex_pathname = NULL; | ||
510 | |||
511 | /* fs locations */ | ||
512 | exp.ex_fslocs.locations = NULL; | ||
513 | exp.ex_fslocs.locations_count = 0; | ||
514 | exp.ex_fslocs.migrated = 0; | ||
515 | |||
516 | exp.ex_uuid = NULL; | ||
517 | |||
518 | /* secinfo */ | ||
519 | exp.ex_nflavors = 0; | ||
520 | |||
521 | if (mesg[mlen-1] != '\n') | 505 | if (mesg[mlen-1] != '\n') |
522 | return -EINVAL; | 506 | return -EINVAL; |
523 | mesg[mlen-1] = 0; | 507 | mesg[mlen-1] = 0; |
524 | 508 | ||
525 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 509 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
526 | err = -ENOMEM; | 510 | if (!buf) |
527 | if (!buf) goto out; | 511 | return -ENOMEM; |
528 | 512 | ||
529 | /* client */ | 513 | /* client */ |
530 | len = qword_get(&mesg, buf, PAGE_SIZE); | ||
531 | err = -EINVAL; | 514 | err = -EINVAL; |
532 | if (len <= 0) goto out; | 515 | len = qword_get(&mesg, buf, PAGE_SIZE); |
516 | if (len <= 0) | ||
517 | goto out; | ||
533 | 518 | ||
534 | err = -ENOENT; | 519 | err = -ENOENT; |
535 | dom = auth_domain_find(buf); | 520 | dom = auth_domain_find(buf); |
@@ -538,25 +523,25 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
538 | 523 | ||
539 | /* path */ | 524 | /* path */ |
540 | err = -EINVAL; | 525 | err = -EINVAL; |
541 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) | 526 | if ((len = qword_get(&mesg, buf, PAGE_SIZE)) <= 0) |
542 | goto out; | 527 | goto out1; |
543 | err = path_lookup(buf, 0, &nd); | 528 | |
544 | if (err) goto out_no_path; | 529 | err = kern_path(buf, 0, &exp.ex_path); |
530 | if (err) | ||
531 | goto out1; | ||
545 | 532 | ||
546 | exp.h.flags = 0; | ||
547 | exp.ex_client = dom; | 533 | exp.ex_client = dom; |
548 | exp.ex_path.mnt = nd.path.mnt; | 534 | |
549 | exp.ex_path.dentry = nd.path.dentry; | ||
550 | exp.ex_pathname = kstrdup(buf, GFP_KERNEL); | ||
551 | err = -ENOMEM; | 535 | err = -ENOMEM; |
536 | exp.ex_pathname = kstrdup(buf, GFP_KERNEL); | ||
552 | if (!exp.ex_pathname) | 537 | if (!exp.ex_pathname) |
553 | goto out; | 538 | goto out2; |
554 | 539 | ||
555 | /* expiry */ | 540 | /* expiry */ |
556 | err = -EINVAL; | 541 | err = -EINVAL; |
557 | exp.h.expiry_time = get_expiry(&mesg); | 542 | exp.h.expiry_time = get_expiry(&mesg); |
558 | if (exp.h.expiry_time == 0) | 543 | if (exp.h.expiry_time == 0) |
559 | goto out; | 544 | goto out3; |
560 | 545 | ||
561 | /* flags */ | 546 | /* flags */ |
562 | err = get_int(&mesg, &an_int); | 547 | err = get_int(&mesg, &an_int); |
@@ -564,22 +549,26 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
564 | err = 0; | 549 | err = 0; |
565 | set_bit(CACHE_NEGATIVE, &exp.h.flags); | 550 | set_bit(CACHE_NEGATIVE, &exp.h.flags); |
566 | } else { | 551 | } else { |
567 | if (err || an_int < 0) goto out; | 552 | if (err || an_int < 0) |
553 | goto out3; | ||
568 | exp.ex_flags= an_int; | 554 | exp.ex_flags= an_int; |
569 | 555 | ||
570 | /* anon uid */ | 556 | /* anon uid */ |
571 | err = get_int(&mesg, &an_int); | 557 | err = get_int(&mesg, &an_int); |
572 | if (err) goto out; | 558 | if (err) |
559 | goto out3; | ||
573 | exp.ex_anon_uid= an_int; | 560 | exp.ex_anon_uid= an_int; |
574 | 561 | ||
575 | /* anon gid */ | 562 | /* anon gid */ |
576 | err = get_int(&mesg, &an_int); | 563 | err = get_int(&mesg, &an_int); |
577 | if (err) goto out; | 564 | if (err) |
565 | goto out3; | ||
578 | exp.ex_anon_gid= an_int; | 566 | exp.ex_anon_gid= an_int; |
579 | 567 | ||
580 | /* fsid */ | 568 | /* fsid */ |
581 | err = get_int(&mesg, &an_int); | 569 | err = get_int(&mesg, &an_int); |
582 | if (err) goto out; | 570 | if (err) |
571 | goto out3; | ||
583 | exp.ex_fsid = an_int; | 572 | exp.ex_fsid = an_int; |
584 | 573 | ||
585 | while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) { | 574 | while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) { |
@@ -605,12 +594,13 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
605 | */ | 594 | */ |
606 | break; | 595 | break; |
607 | if (err) | 596 | if (err) |
608 | goto out; | 597 | goto out4; |
609 | } | 598 | } |
610 | 599 | ||
611 | err = check_export(nd.path.dentry->d_inode, exp.ex_flags, | 600 | err = check_export(exp.ex_path.dentry->d_inode, exp.ex_flags, |
612 | exp.ex_uuid); | 601 | exp.ex_uuid); |
613 | if (err) goto out; | 602 | if (err) |
603 | goto out4; | ||
614 | } | 604 | } |
615 | 605 | ||
616 | expp = svc_export_lookup(&exp); | 606 | expp = svc_export_lookup(&exp); |
@@ -623,15 +613,16 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
623 | err = -ENOMEM; | 613 | err = -ENOMEM; |
624 | else | 614 | else |
625 | exp_put(expp); | 615 | exp_put(expp); |
626 | out: | 616 | out4: |
627 | nfsd4_fslocs_free(&exp.ex_fslocs); | 617 | nfsd4_fslocs_free(&exp.ex_fslocs); |
628 | kfree(exp.ex_uuid); | 618 | kfree(exp.ex_uuid); |
619 | out3: | ||
629 | kfree(exp.ex_pathname); | 620 | kfree(exp.ex_pathname); |
630 | if (nd.path.dentry) | 621 | out2: |
631 | path_put(&nd.path); | 622 | path_put(&exp.ex_path); |
632 | out_no_path: | 623 | out1: |
633 | if (dom) | 624 | auth_domain_put(dom); |
634 | auth_domain_put(dom); | 625 | out: |
635 | kfree(buf); | 626 | kfree(buf); |
636 | return err; | 627 | return err; |
637 | } | 628 | } |
@@ -999,7 +990,7 @@ exp_export(struct nfsctl_export *nxp) | |||
999 | struct svc_export *exp = NULL; | 990 | struct svc_export *exp = NULL; |
1000 | struct svc_export new; | 991 | struct svc_export new; |
1001 | struct svc_expkey *fsid_key = NULL; | 992 | struct svc_expkey *fsid_key = NULL; |
1002 | struct nameidata nd; | 993 | struct path path; |
1003 | int err; | 994 | int err; |
1004 | 995 | ||
1005 | /* Consistency check */ | 996 | /* Consistency check */ |
@@ -1022,12 +1013,12 @@ exp_export(struct nfsctl_export *nxp) | |||
1022 | 1013 | ||
1023 | 1014 | ||
1024 | /* Look up the dentry */ | 1015 | /* Look up the dentry */ |
1025 | err = path_lookup(nxp->ex_path, 0, &nd); | 1016 | err = kern_path(nxp->ex_path, 0, &path); |
1026 | if (err) | 1017 | if (err) |
1027 | goto out_put_clp; | 1018 | goto out_put_clp; |
1028 | err = -EINVAL; | 1019 | err = -EINVAL; |
1029 | 1020 | ||
1030 | exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL); | 1021 | exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL); |
1031 | 1022 | ||
1032 | memset(&new, 0, sizeof(new)); | 1023 | memset(&new, 0, sizeof(new)); |
1033 | 1024 | ||
@@ -1035,8 +1026,8 @@ exp_export(struct nfsctl_export *nxp) | |||
1035 | if ((nxp->ex_flags & NFSEXP_FSID) && | 1026 | if ((nxp->ex_flags & NFSEXP_FSID) && |
1036 | (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) && | 1027 | (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) && |
1037 | fsid_key->ek_path.mnt && | 1028 | fsid_key->ek_path.mnt && |
1038 | (fsid_key->ek_path.mnt != nd.path.mnt || | 1029 | (fsid_key->ek_path.mnt != path.mnt || |
1039 | fsid_key->ek_path.dentry != nd.path.dentry)) | 1030 | fsid_key->ek_path.dentry != path.dentry)) |
1040 | goto finish; | 1031 | goto finish; |
1041 | 1032 | ||
1042 | if (!IS_ERR(exp)) { | 1033 | if (!IS_ERR(exp)) { |
@@ -1052,7 +1043,7 @@ exp_export(struct nfsctl_export *nxp) | |||
1052 | goto finish; | 1043 | goto finish; |
1053 | } | 1044 | } |
1054 | 1045 | ||
1055 | err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL); | 1046 | err = check_export(path.dentry->d_inode, nxp->ex_flags, NULL); |
1056 | if (err) goto finish; | 1047 | if (err) goto finish; |
1057 | 1048 | ||
1058 | err = -ENOMEM; | 1049 | err = -ENOMEM; |
@@ -1065,7 +1056,7 @@ exp_export(struct nfsctl_export *nxp) | |||
1065 | if (!new.ex_pathname) | 1056 | if (!new.ex_pathname) |
1066 | goto finish; | 1057 | goto finish; |
1067 | new.ex_client = clp; | 1058 | new.ex_client = clp; |
1068 | new.ex_path = nd.path; | 1059 | new.ex_path = path; |
1069 | new.ex_flags = nxp->ex_flags; | 1060 | new.ex_flags = nxp->ex_flags; |
1070 | new.ex_anon_uid = nxp->ex_anon_uid; | 1061 | new.ex_anon_uid = nxp->ex_anon_uid; |
1071 | new.ex_anon_gid = nxp->ex_anon_gid; | 1062 | new.ex_anon_gid = nxp->ex_anon_gid; |
@@ -1091,7 +1082,7 @@ finish: | |||
1091 | exp_put(exp); | 1082 | exp_put(exp); |
1092 | if (fsid_key && !IS_ERR(fsid_key)) | 1083 | if (fsid_key && !IS_ERR(fsid_key)) |
1093 | cache_put(&fsid_key->h, &svc_expkey_cache); | 1084 | cache_put(&fsid_key->h, &svc_expkey_cache); |
1094 | path_put(&nd.path); | 1085 | path_put(&path); |
1095 | out_put_clp: | 1086 | out_put_clp: |
1096 | auth_domain_put(clp); | 1087 | auth_domain_put(clp); |
1097 | out_unlock: | 1088 | out_unlock: |
@@ -1122,7 +1113,7 @@ exp_unexport(struct nfsctl_export *nxp) | |||
1122 | { | 1113 | { |
1123 | struct auth_domain *dom; | 1114 | struct auth_domain *dom; |
1124 | svc_export *exp; | 1115 | svc_export *exp; |
1125 | struct nameidata nd; | 1116 | struct path path; |
1126 | int err; | 1117 | int err; |
1127 | 1118 | ||
1128 | /* Consistency check */ | 1119 | /* Consistency check */ |
@@ -1139,13 +1130,13 @@ exp_unexport(struct nfsctl_export *nxp) | |||
1139 | goto out_unlock; | 1130 | goto out_unlock; |
1140 | } | 1131 | } |
1141 | 1132 | ||
1142 | err = path_lookup(nxp->ex_path, 0, &nd); | 1133 | err = kern_path(nxp->ex_path, 0, &path); |
1143 | if (err) | 1134 | if (err) |
1144 | goto out_domain; | 1135 | goto out_domain; |
1145 | 1136 | ||
1146 | err = -EINVAL; | 1137 | err = -EINVAL; |
1147 | exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL); | 1138 | exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL); |
1148 | path_put(&nd.path); | 1139 | path_put(&path); |
1149 | if (IS_ERR(exp)) | 1140 | if (IS_ERR(exp)) |
1150 | goto out_domain; | 1141 | goto out_domain; |
1151 | 1142 | ||
@@ -1167,26 +1158,26 @@ out_unlock: | |||
1167 | * since its harder to fool a kernel module than a user space program. | 1158 | * since its harder to fool a kernel module than a user space program. |
1168 | */ | 1159 | */ |
1169 | int | 1160 | int |
1170 | exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) | 1161 | exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize) |
1171 | { | 1162 | { |
1172 | struct svc_export *exp; | 1163 | struct svc_export *exp; |
1173 | struct nameidata nd; | 1164 | struct path path; |
1174 | struct inode *inode; | 1165 | struct inode *inode; |
1175 | struct svc_fh fh; | 1166 | struct svc_fh fh; |
1176 | int err; | 1167 | int err; |
1177 | 1168 | ||
1178 | err = -EPERM; | 1169 | err = -EPERM; |
1179 | /* NB: we probably ought to check that it's NUL-terminated */ | 1170 | /* NB: we probably ought to check that it's NUL-terminated */ |
1180 | if (path_lookup(path, 0, &nd)) { | 1171 | if (kern_path(name, 0, &path)) { |
1181 | printk("nfsd: exp_rootfh path not found %s", path); | 1172 | printk("nfsd: exp_rootfh path not found %s", name); |
1182 | return err; | 1173 | return err; |
1183 | } | 1174 | } |
1184 | inode = nd.path.dentry->d_inode; | 1175 | inode = path.dentry->d_inode; |
1185 | 1176 | ||
1186 | dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", | 1177 | dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", |
1187 | path, nd.path.dentry, clp->name, | 1178 | name, path.dentry, clp->name, |
1188 | inode->i_sb->s_id, inode->i_ino); | 1179 | inode->i_sb->s_id, inode->i_ino); |
1189 | exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL); | 1180 | exp = exp_parent(clp, path.mnt, path.dentry, NULL); |
1190 | if (IS_ERR(exp)) { | 1181 | if (IS_ERR(exp)) { |
1191 | err = PTR_ERR(exp); | 1182 | err = PTR_ERR(exp); |
1192 | goto out; | 1183 | goto out; |
@@ -1196,7 +1187,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) | |||
1196 | * fh must be initialized before calling fh_compose | 1187 | * fh must be initialized before calling fh_compose |
1197 | */ | 1188 | */ |
1198 | fh_init(&fh, maxsize); | 1189 | fh_init(&fh, maxsize); |
1199 | if (fh_compose(&fh, exp, nd.path.dentry, NULL)) | 1190 | if (fh_compose(&fh, exp, path.dentry, NULL)) |
1200 | err = -EINVAL; | 1191 | err = -EINVAL; |
1201 | else | 1192 | else |
1202 | err = 0; | 1193 | err = 0; |
@@ -1204,7 +1195,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) | |||
1204 | fh_put(&fh); | 1195 | fh_put(&fh); |
1205 | exp_put(exp); | 1196 | exp_put(exp); |
1206 | out: | 1197 | out: |
1207 | path_put(&nd.path); | 1198 | path_put(&path); |
1208 | return err; | 1199 | return err; |
1209 | } | 1200 | } |
1210 | 1201 | ||