aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/export.c')
-rw-r--r--fs/nfsd/export.c122
1 files changed, 58 insertions, 64 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 346570f6d848..8a6f7c924c75 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -63,10 +63,8 @@ static void expkey_put(struct kref *ref)
63 struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); 63 struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
64 64
65 if (test_bit(CACHE_VALID, &key->h.flags) && 65 if (test_bit(CACHE_VALID, &key->h.flags) &&
66 !test_bit(CACHE_NEGATIVE, &key->h.flags)) { 66 !test_bit(CACHE_NEGATIVE, &key->h.flags))
67 dput(key->ek_dentry); 67 path_put(&key->ek_path);
68 mntput(key->ek_mnt);
69 }
70 auth_domain_put(key->ek_client); 68 auth_domain_put(key->ek_client);
71 kfree(key); 69 kfree(key);
72} 70}
@@ -169,15 +167,14 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
169 goto out; 167 goto out;
170 168
171 dprintk("Found the path %s\n", buf); 169 dprintk("Found the path %s\n", buf);
172 key.ek_mnt = nd.mnt; 170 key.ek_path = nd.path;
173 key.ek_dentry = nd.dentry; 171
174
175 ek = svc_expkey_update(&key, ek); 172 ek = svc_expkey_update(&key, ek);
176 if (ek) 173 if (ek)
177 cache_put(&ek->h, &svc_expkey_cache); 174 cache_put(&ek->h, &svc_expkey_cache);
178 else 175 else
179 err = -ENOMEM; 176 err = -ENOMEM;
180 path_release(&nd); 177 path_put(&nd.path);
181 } 178 }
182 cache_flush(); 179 cache_flush();
183 out: 180 out:
@@ -206,7 +203,7 @@ static int expkey_show(struct seq_file *m,
206 if (test_bit(CACHE_VALID, &h->flags) && 203 if (test_bit(CACHE_VALID, &h->flags) &&
207 !test_bit(CACHE_NEGATIVE, &h->flags)) { 204 !test_bit(CACHE_NEGATIVE, &h->flags)) {
208 seq_printf(m, " "); 205 seq_printf(m, " ");
209 seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n"); 206 seq_path(m, &ek->ek_path, "\\ \t\n");
210 } 207 }
211 seq_printf(m, "\n"); 208 seq_printf(m, "\n");
212 return 0; 209 return 0;
@@ -243,8 +240,8 @@ static inline void expkey_update(struct cache_head *cnew,
243 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h); 240 struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
244 struct svc_expkey *item = container_of(citem, struct svc_expkey, h); 241 struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
245 242
246 new->ek_mnt = mntget(item->ek_mnt); 243 new->ek_path = item->ek_path;
247 new->ek_dentry = dget(item->ek_dentry); 244 path_get(&item->ek_path);
248} 245}
249 246
250static struct cache_head *expkey_alloc(void) 247static struct cache_head *expkey_alloc(void)
@@ -332,10 +329,9 @@ static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
332static void svc_export_put(struct kref *ref) 329static void svc_export_put(struct kref *ref)
333{ 330{
334 struct svc_export *exp = container_of(ref, struct svc_export, h.ref); 331 struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
335 dput(exp->ex_dentry); 332 path_put(&exp->ex_path);
336 mntput(exp->ex_mnt);
337 auth_domain_put(exp->ex_client); 333 auth_domain_put(exp->ex_client);
338 kfree(exp->ex_path); 334 kfree(exp->ex_pathname);
339 nfsd4_fslocs_free(&exp->ex_fslocs); 335 nfsd4_fslocs_free(&exp->ex_fslocs);
340 kfree(exp); 336 kfree(exp);
341} 337}
@@ -349,7 +345,7 @@ static void svc_export_request(struct cache_detail *cd,
349 char *pth; 345 char *pth;
350 346
351 qword_add(bpp, blen, exp->ex_client->name); 347 qword_add(bpp, blen, exp->ex_client->name);
352 pth = d_path(exp->ex_dentry, exp->ex_mnt, *bpp, *blen); 348 pth = d_path(&exp->ex_path, *bpp, *blen);
353 if (IS_ERR(pth)) { 349 if (IS_ERR(pth)) {
354 /* is this correct? */ 350 /* is this correct? */
355 (*bpp)[0] = '\n'; 351 (*bpp)[0] = '\n';
@@ -507,8 +503,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
507 struct svc_export exp, *expp; 503 struct svc_export exp, *expp;
508 int an_int; 504 int an_int;
509 505
510 nd.dentry = NULL; 506 nd.path.dentry = NULL;
511 exp.ex_path = NULL; 507 exp.ex_pathname = NULL;
512 508
513 /* fs locations */ 509 /* fs locations */
514 exp.ex_fslocs.locations = NULL; 510 exp.ex_fslocs.locations = NULL;
@@ -547,11 +543,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
547 543
548 exp.h.flags = 0; 544 exp.h.flags = 0;
549 exp.ex_client = dom; 545 exp.ex_client = dom;
550 exp.ex_mnt = nd.mnt; 546 exp.ex_path.mnt = nd.path.mnt;
551 exp.ex_dentry = nd.dentry; 547 exp.ex_path.dentry = nd.path.dentry;
552 exp.ex_path = kstrdup(buf, GFP_KERNEL); 548 exp.ex_pathname = kstrdup(buf, GFP_KERNEL);
553 err = -ENOMEM; 549 err = -ENOMEM;
554 if (!exp.ex_path) 550 if (!exp.ex_pathname)
555 goto out; 551 goto out;
556 552
557 /* expiry */ 553 /* expiry */
@@ -610,7 +606,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
610 goto out; 606 goto out;
611 } 607 }
612 608
613 err = check_export(nd.dentry->d_inode, exp.ex_flags, 609 err = check_export(nd.path.dentry->d_inode, exp.ex_flags,
614 exp.ex_uuid); 610 exp.ex_uuid);
615 if (err) goto out; 611 if (err) goto out;
616 } 612 }
@@ -628,9 +624,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
628 out: 624 out:
629 nfsd4_fslocs_free(&exp.ex_fslocs); 625 nfsd4_fslocs_free(&exp.ex_fslocs);
630 kfree(exp.ex_uuid); 626 kfree(exp.ex_uuid);
631 kfree(exp.ex_path); 627 kfree(exp.ex_pathname);
632 if (nd.dentry) 628 if (nd.path.dentry)
633 path_release(&nd); 629 path_put(&nd.path);
634 out_no_path: 630 out_no_path:
635 if (dom) 631 if (dom)
636 auth_domain_put(dom); 632 auth_domain_put(dom);
@@ -653,7 +649,7 @@ static int svc_export_show(struct seq_file *m,
653 return 0; 649 return 0;
654 } 650 }
655 exp = container_of(h, struct svc_export, h); 651 exp = container_of(h, struct svc_export, h);
656 seq_path(m, exp->ex_mnt, exp->ex_dentry, " \t\n\\"); 652 seq_path(m, &exp->ex_path, " \t\n\\");
657 seq_putc(m, '\t'); 653 seq_putc(m, '\t');
658 seq_escape(m, exp->ex_client->name, " \t\n\\"); 654 seq_escape(m, exp->ex_client->name, " \t\n\\");
659 seq_putc(m, '('); 655 seq_putc(m, '(');
@@ -680,8 +676,8 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b)
680 struct svc_export *orig = container_of(a, struct svc_export, h); 676 struct svc_export *orig = container_of(a, struct svc_export, h);
681 struct svc_export *new = container_of(b, struct svc_export, h); 677 struct svc_export *new = container_of(b, struct svc_export, h);
682 return orig->ex_client == new->ex_client && 678 return orig->ex_client == new->ex_client &&
683 orig->ex_dentry == new->ex_dentry && 679 orig->ex_path.dentry == new->ex_path.dentry &&
684 orig->ex_mnt == new->ex_mnt; 680 orig->ex_path.mnt == new->ex_path.mnt;
685} 681}
686 682
687static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) 683static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
@@ -691,9 +687,9 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
691 687
692 kref_get(&item->ex_client->ref); 688 kref_get(&item->ex_client->ref);
693 new->ex_client = item->ex_client; 689 new->ex_client = item->ex_client;
694 new->ex_dentry = dget(item->ex_dentry); 690 new->ex_path.dentry = dget(item->ex_path.dentry);
695 new->ex_mnt = mntget(item->ex_mnt); 691 new->ex_path.mnt = mntget(item->ex_path.mnt);
696 new->ex_path = NULL; 692 new->ex_pathname = NULL;
697 new->ex_fslocs.locations = NULL; 693 new->ex_fslocs.locations = NULL;
698 new->ex_fslocs.locations_count = 0; 694 new->ex_fslocs.locations_count = 0;
699 new->ex_fslocs.migrated = 0; 695 new->ex_fslocs.migrated = 0;
@@ -711,8 +707,8 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
711 new->ex_fsid = item->ex_fsid; 707 new->ex_fsid = item->ex_fsid;
712 new->ex_uuid = item->ex_uuid; 708 new->ex_uuid = item->ex_uuid;
713 item->ex_uuid = NULL; 709 item->ex_uuid = NULL;
714 new->ex_path = item->ex_path; 710 new->ex_pathname = item->ex_pathname;
715 item->ex_path = NULL; 711 item->ex_pathname = NULL;
716 new->ex_fslocs.locations = item->ex_fslocs.locations; 712 new->ex_fslocs.locations = item->ex_fslocs.locations;
717 item->ex_fslocs.locations = NULL; 713 item->ex_fslocs.locations = NULL;
718 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count; 714 new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
@@ -755,8 +751,8 @@ svc_export_lookup(struct svc_export *exp)
755 struct cache_head *ch; 751 struct cache_head *ch;
756 int hash; 752 int hash;
757 hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS); 753 hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
758 hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS); 754 hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS);
759 hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS); 755 hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS);
760 756
761 ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h, 757 ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h,
762 hash); 758 hash);
@@ -772,8 +768,8 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
772 struct cache_head *ch; 768 struct cache_head *ch;
773 int hash; 769 int hash;
774 hash = hash_ptr(old->ex_client, EXPORT_HASHBITS); 770 hash = hash_ptr(old->ex_client, EXPORT_HASHBITS);
775 hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS); 771 hash ^= hash_ptr(old->ex_path.dentry, EXPORT_HASHBITS);
776 hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS); 772 hash ^= hash_ptr(old->ex_path.mnt, EXPORT_HASHBITS);
777 773
778 ch = sunrpc_cache_update(&svc_export_cache, &new->h, 774 ch = sunrpc_cache_update(&svc_export_cache, &new->h,
779 &old->h, 775 &old->h,
@@ -815,8 +811,7 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv,
815 key.ek_client = clp; 811 key.ek_client = clp;
816 key.ek_fsidtype = fsid_type; 812 key.ek_fsidtype = fsid_type;
817 memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); 813 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
818 key.ek_mnt = exp->ex_mnt; 814 key.ek_path = exp->ex_path;
819 key.ek_dentry = exp->ex_dentry;
820 key.h.expiry_time = NEVER; 815 key.h.expiry_time = NEVER;
821 key.h.flags = 0; 816 key.h.flags = 0;
822 817
@@ -865,13 +860,13 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
865{ 860{
866 struct svc_export *exp, key; 861 struct svc_export *exp, key;
867 int err; 862 int err;
868 863
869 if (!clp) 864 if (!clp)
870 return ERR_PTR(-ENOENT); 865 return ERR_PTR(-ENOENT);
871 866
872 key.ex_client = clp; 867 key.ex_client = clp;
873 key.ex_mnt = mnt; 868 key.ex_path.mnt = mnt;
874 key.ex_dentry = dentry; 869 key.ex_path.dentry = dentry;
875 870
876 exp = svc_export_lookup(&key); 871 exp = svc_export_lookup(&key);
877 if (exp == NULL) 872 if (exp == NULL)
@@ -968,7 +963,7 @@ static int exp_fsid_hash(svc_client *clp, struct svc_export *exp)
968static int exp_hash(struct auth_domain *clp, struct svc_export *exp) 963static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
969{ 964{
970 u32 fsid[2]; 965 u32 fsid[2];
971 struct inode *inode = exp->ex_dentry->d_inode; 966 struct inode *inode = exp->ex_path.dentry->d_inode;
972 dev_t dev = inode->i_sb->s_dev; 967 dev_t dev = inode->i_sb->s_dev;
973 968
974 if (old_valid_dev(dev)) { 969 if (old_valid_dev(dev)) {
@@ -982,7 +977,7 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
982static void exp_unhash(struct svc_export *exp) 977static void exp_unhash(struct svc_export *exp)
983{ 978{
984 struct svc_expkey *ek; 979 struct svc_expkey *ek;
985 struct inode *inode = exp->ex_dentry->d_inode; 980 struct inode *inode = exp->ex_path.dentry->d_inode;
986 981
987 ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); 982 ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino);
988 if (!IS_ERR(ek)) { 983 if (!IS_ERR(ek)) {
@@ -1030,15 +1025,16 @@ exp_export(struct nfsctl_export *nxp)
1030 goto out_unlock; 1025 goto out_unlock;
1031 err = -EINVAL; 1026 err = -EINVAL;
1032 1027
1033 exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); 1028 exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
1034 1029
1035 memset(&new, 0, sizeof(new)); 1030 memset(&new, 0, sizeof(new));
1036 1031
1037 /* must make sure there won't be an ex_fsid clash */ 1032 /* must make sure there won't be an ex_fsid clash */
1038 if ((nxp->ex_flags & NFSEXP_FSID) && 1033 if ((nxp->ex_flags & NFSEXP_FSID) &&
1039 (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) && 1034 (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
1040 fsid_key->ek_mnt && 1035 fsid_key->ek_path.mnt &&
1041 (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) ) 1036 (fsid_key->ek_path.mnt != nd.path.mnt ||
1037 fsid_key->ek_path.dentry != nd.path.dentry))
1042 goto finish; 1038 goto finish;
1043 1039
1044 if (!IS_ERR(exp)) { 1040 if (!IS_ERR(exp)) {
@@ -1054,7 +1050,7 @@ exp_export(struct nfsctl_export *nxp)
1054 goto finish; 1050 goto finish;
1055 } 1051 }
1056 1052
1057 err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL); 1053 err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
1058 if (err) goto finish; 1054 if (err) goto finish;
1059 1055
1060 err = -ENOMEM; 1056 err = -ENOMEM;
@@ -1063,12 +1059,11 @@ exp_export(struct nfsctl_export *nxp)
1063 1059
1064 new.h.expiry_time = NEVER; 1060 new.h.expiry_time = NEVER;
1065 new.h.flags = 0; 1061 new.h.flags = 0;
1066 new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); 1062 new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL);
1067 if (!new.ex_path) 1063 if (!new.ex_pathname)
1068 goto finish; 1064 goto finish;
1069 new.ex_client = clp; 1065 new.ex_client = clp;
1070 new.ex_mnt = nd.mnt; 1066 new.ex_path = nd.path;
1071 new.ex_dentry = nd.dentry;
1072 new.ex_flags = nxp->ex_flags; 1067 new.ex_flags = nxp->ex_flags;
1073 new.ex_anon_uid = nxp->ex_anon_uid; 1068 new.ex_anon_uid = nxp->ex_anon_uid;
1074 new.ex_anon_gid = nxp->ex_anon_gid; 1069 new.ex_anon_gid = nxp->ex_anon_gid;
@@ -1089,15 +1084,14 @@ exp_export(struct nfsctl_export *nxp)
1089 } else 1084 } else
1090 err = 0; 1085 err = 0;
1091finish: 1086finish:
1092 if (new.ex_path) 1087 kfree(new.ex_pathname);
1093 kfree(new.ex_path);
1094 if (exp) 1088 if (exp)
1095 exp_put(exp); 1089 exp_put(exp);
1096 if (fsid_key && !IS_ERR(fsid_key)) 1090 if (fsid_key && !IS_ERR(fsid_key))
1097 cache_put(&fsid_key->h, &svc_expkey_cache); 1091 cache_put(&fsid_key->h, &svc_expkey_cache);
1098 if (clp) 1092 if (clp)
1099 auth_domain_put(clp); 1093 auth_domain_put(clp);
1100 path_release(&nd); 1094 path_put(&nd.path);
1101out_unlock: 1095out_unlock:
1102 exp_writeunlock(); 1096 exp_writeunlock();
1103out: 1097out:
@@ -1148,8 +1142,8 @@ exp_unexport(struct nfsctl_export *nxp)
1148 goto out_domain; 1142 goto out_domain;
1149 1143
1150 err = -EINVAL; 1144 err = -EINVAL;
1151 exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); 1145 exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
1152 path_release(&nd); 1146 path_put(&nd.path);
1153 if (IS_ERR(exp)) 1147 if (IS_ERR(exp))
1154 goto out_domain; 1148 goto out_domain;
1155 1149
@@ -1185,12 +1179,12 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
1185 printk("nfsd: exp_rootfh path not found %s", path); 1179 printk("nfsd: exp_rootfh path not found %s", path);
1186 return err; 1180 return err;
1187 } 1181 }
1188 inode = nd.dentry->d_inode; 1182 inode = nd.path.dentry->d_inode;
1189 1183
1190 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", 1184 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
1191 path, nd.dentry, clp->name, 1185 path, nd.path.dentry, clp->name,
1192 inode->i_sb->s_id, inode->i_ino); 1186 inode->i_sb->s_id, inode->i_ino);
1193 exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); 1187 exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
1194 if (IS_ERR(exp)) { 1188 if (IS_ERR(exp)) {
1195 err = PTR_ERR(exp); 1189 err = PTR_ERR(exp);
1196 goto out; 1190 goto out;
@@ -1200,7 +1194,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
1200 * fh must be initialized before calling fh_compose 1194 * fh must be initialized before calling fh_compose
1201 */ 1195 */
1202 fh_init(&fh, maxsize); 1196 fh_init(&fh, maxsize);
1203 if (fh_compose(&fh, exp, nd.dentry, NULL)) 1197 if (fh_compose(&fh, exp, nd.path.dentry, NULL))
1204 err = -EINVAL; 1198 err = -EINVAL;
1205 else 1199 else
1206 err = 0; 1200 err = 0;
@@ -1208,7 +1202,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
1208 fh_put(&fh); 1202 fh_put(&fh);
1209 exp_put(exp); 1203 exp_put(exp);
1210out: 1204out:
1211 path_release(&nd); 1205 path_put(&nd.path);
1212 return err; 1206 return err;
1213} 1207}
1214 1208
@@ -1220,7 +1214,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
1220 if (IS_ERR(ek)) 1214 if (IS_ERR(ek))
1221 return ERR_CAST(ek); 1215 return ERR_CAST(ek);
1222 1216
1223 exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp); 1217 exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp);
1224 cache_put(&ek->h, &svc_expkey_cache); 1218 cache_put(&ek->h, &svc_expkey_cache);
1225 1219
1226 if (IS_ERR(exp)) 1220 if (IS_ERR(exp))
@@ -1359,7 +1353,7 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
1359 exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); 1353 exp = rqst_exp_find(rqstp, FSID_NUM, fsidv);
1360 if (IS_ERR(exp)) 1354 if (IS_ERR(exp))
1361 return nfserrno(PTR_ERR(exp)); 1355 return nfserrno(PTR_ERR(exp));
1362 rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); 1356 rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
1363 if (rv) 1357 if (rv)
1364 goto out; 1358 goto out;
1365 rv = check_nfsd_access(exp, rqstp); 1359 rv = check_nfsd_access(exp, rqstp);