hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/fs/nfsd/export.c
....@@ -22,6 +22,8 @@
2222 #include "nfsfh.h"
2323 #include "netns.h"
2424 #include "pnfs.h"
25
+#include "filecache.h"
26
+#include "trace.h"
2527
2628 #define NFSDDBG_FACILITY NFSDDBG_EXPORT
2729
....@@ -46,7 +48,12 @@
4648 !test_bit(CACHE_NEGATIVE, &key->h.flags))
4749 path_put(&key->ek_path);
4850 auth_domain_put(key->ek_client);
49
- kfree(key);
51
+ kfree_rcu(key, ek_rcu);
52
+}
53
+
54
+static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
55
+{
56
+ return sunrpc_cache_pipe_upcall(cd, h);
5057 }
5158
5259 static void expkey_request(struct cache_detail *cd,
....@@ -139,7 +146,9 @@
139146 if (len == 0) {
140147 set_bit(CACHE_NEGATIVE, &key.h.flags);
141148 ek = svc_expkey_update(cd, &key, ek);
142
- if (!ek)
149
+ if (ek)
150
+ trace_nfsd_expkey_update(ek, NULL);
151
+ else
143152 err = -ENOMEM;
144153 } else {
145154 err = kern_path(buf, 0, &key.ek_path);
....@@ -149,7 +158,9 @@
149158 dprintk("Found the path %s\n", buf);
150159
151160 ek = svc_expkey_update(cd, &key, ek);
152
- if (!ek)
161
+ if (ek)
162
+ trace_nfsd_expkey_update(ek, buf);
163
+ else
153164 err = -ENOMEM;
154165 path_put(&key.ek_path);
155166 }
....@@ -232,11 +243,23 @@
232243 return NULL;
233244 }
234245
246
+static void expkey_flush(void)
247
+{
248
+ /*
249
+ * Take the nfsd_mutex here to ensure that the file cache is not
250
+ * destroyed while we're in the middle of flushing.
251
+ */
252
+ mutex_lock(&nfsd_mutex);
253
+ nfsd_file_cache_purge(current->nsproxy->net_ns);
254
+ mutex_unlock(&nfsd_mutex);
255
+}
256
+
235257 static const struct cache_detail svc_expkey_cache_template = {
236258 .owner = THIS_MODULE,
237259 .hash_size = EXPKEY_HASHMAX,
238260 .name = "nfsd.fh",
239261 .cache_put = expkey_put,
262
+ .cache_upcall = expkey_upcall,
240263 .cache_request = expkey_request,
241264 .cache_parse = expkey_parse,
242265 .cache_show = expkey_show,
....@@ -244,6 +267,7 @@
244267 .init = expkey_init,
245268 .update = expkey_update,
246269 .alloc = expkey_alloc,
270
+ .flush = expkey_flush,
247271 };
248272
249273 static int
....@@ -265,7 +289,7 @@
265289 struct cache_head *ch;
266290 int hash = svc_expkey_hash(item);
267291
268
- ch = sunrpc_cache_lookup(cd, &item->h, hash);
292
+ ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
269293 if (ch)
270294 return container_of(ch, struct svc_expkey, h);
271295 else
....@@ -314,7 +338,12 @@
314338 auth_domain_put(exp->ex_client);
315339 nfsd4_fslocs_free(&exp->ex_fslocs);
316340 kfree(exp->ex_uuid);
317
- kfree(exp);
341
+ kfree_rcu(exp, ex_rcu);
342
+}
343
+
344
+static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
345
+{
346
+ return sunrpc_cache_pipe_upcall(cd, h);
318347 }
319348
320349 static void svc_export_request(struct cache_detail *cd,
....@@ -570,13 +599,13 @@
570599 err = get_int(&mesg, &an_int);
571600 if (err)
572601 goto out3;
573
- exp.ex_anon_uid= make_kuid(&init_user_ns, an_int);
602
+ exp.ex_anon_uid= make_kuid(current_user_ns(), an_int);
574603
575604 /* anon gid */
576605 err = get_int(&mesg, &an_int);
577606 if (err)
578607 goto out3;
579
- exp.ex_anon_gid= make_kgid(&init_user_ns, an_int);
608
+ exp.ex_anon_gid= make_kgid(current_user_ns(), an_int);
580609
581610 /* fsid */
582611 err = get_int(&mesg, &an_int);
....@@ -630,15 +659,17 @@
630659 }
631660
632661 expp = svc_export_lookup(&exp);
633
- if (expp)
634
- expp = svc_export_update(&exp, expp);
635
- else
662
+ if (!expp) {
636663 err = -ENOMEM;
637
- cache_flush();
638
- if (expp == NULL)
639
- err = -ENOMEM;
640
- else
664
+ goto out4;
665
+ }
666
+ expp = svc_export_update(&exp, expp);
667
+ if (expp) {
668
+ trace_nfsd_export_update(expp);
669
+ cache_flush();
641670 exp_put(expp);
671
+ } else
672
+ err = -ENOMEM;
642673 out4:
643674 nfsd4_fslocs_free(&exp.ex_fslocs);
644675 kfree(exp.ex_uuid);
....@@ -754,6 +785,7 @@
754785 .hash_size = EXPORT_HASHMAX,
755786 .name = "nfsd.export",
756787 .cache_put = svc_export_put,
788
+ .cache_upcall = svc_export_upcall,
757789 .cache_request = svc_export_request,
758790 .cache_parse = svc_export_parse,
759791 .cache_show = svc_export_show,
....@@ -780,7 +812,7 @@
780812 struct cache_head *ch;
781813 int hash = svc_export_hash(exp);
782814
783
- ch = sunrpc_cache_lookup(exp->cd, &exp->h, hash);
815
+ ch = sunrpc_cache_lookup_rcu(exp->cd, &exp->h, hash);
784816 if (ch)
785817 return container_of(ch, struct svc_export, h);
786818 else
....@@ -819,8 +851,10 @@
819851 if (ek == NULL)
820852 return ERR_PTR(-ENOMEM);
821853 err = cache_check(cd, &ek->h, reqp);
822
- if (err)
854
+ if (err) {
855
+ trace_nfsd_exp_find_key(&key, err);
823856 return ERR_PTR(err);
857
+ }
824858 return ek;
825859 }
826860
....@@ -842,8 +876,10 @@
842876 if (exp == NULL)
843877 return ERR_PTR(-ENOMEM);
844878 err = cache_check(cd, &exp->h, reqp);
845
- if (err)
879
+ if (err) {
880
+ trace_nfsd_exp_get_by_name(&key, err);
846881 return ERR_PTR(err);
882
+ }
847883 return exp;
848884 }
849885
....@@ -966,7 +1002,7 @@
9661002 if (nfsd4_spo_must_allow(rqstp))
9671003 return 0;
9681004
969
- return nfserr_wrongsec;
1005
+ return rqstp->rq_vers < 4 ? nfserr_acces : nfserr_wrongsec;
9701006 }
9711007
9721008 /*
....@@ -1170,15 +1206,17 @@
11701206 static void exp_flags(struct seq_file *m, int flag, int fsid,
11711207 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
11721208 {
1209
+ struct user_namespace *userns = m->file->f_cred->user_ns;
1210
+
11731211 show_expflags(m, flag, NFSEXP_ALLFLAGS);
11741212 if (flag & NFSEXP_FSID)
11751213 seq_printf(m, ",fsid=%d", fsid);
1176
- if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) &&
1177
- !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2)))
1178
- seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu));
1179
- if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) &&
1180
- !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2)))
1181
- seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong));
1214
+ if (!uid_eq(anonu, make_kuid(userns, (uid_t)-2)) &&
1215
+ !uid_eq(anonu, make_kuid(userns, 0x10000-2)))
1216
+ seq_printf(m, ",anonuid=%u", from_kuid_munged(userns, anonu));
1217
+ if (!gid_eq(anong, make_kgid(userns, (gid_t)-2)) &&
1218
+ !gid_eq(anong, make_kgid(userns, 0x10000-2)))
1219
+ seq_printf(m, ",anongid=%u", from_kgid_munged(userns, anong));
11821220 if (fsloc && fsloc->locations_count > 0) {
11831221 char *loctype = (fsloc->migrated) ? "refer" : "replicas";
11841222 int i;
....@@ -1216,9 +1254,9 @@
12161254 }
12171255
12181256 const struct seq_operations nfs_exports_op = {
1219
- .start = cache_seq_start,
1220
- .next = cache_seq_next,
1221
- .stop = cache_seq_stop,
1257
+ .start = cache_seq_start_rcu,
1258
+ .next = cache_seq_next_rcu,
1259
+ .stop = cache_seq_stop_rcu,
12221260 .show = e_show,
12231261 };
12241262