History

Merge tag 'nfsd-4.5' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields: "Smaller bugfixes and cleanup, including a fix for a failures of kerberized NFSv4.1 mounts, and Scott Mayhew's work addressing ACK storms that can affect some high-availability NFS setups" * tag 'nfsd-4.5' of git://linux-nfs.org/~bfields/linux: nfsd: add new io class tracepoint nfsd: give up on CB_LAYOUTRECALLs after two lease periods nfsd: Fix nfsd leaks sunrpc module references lockd: constify nlmsvc_binding structure lockd: use to_delayed_work nfsd: use to_delayed_work Revert "svcrdma: Do not send XDR roundup bytes for a write chunk" lockd: Register callbacks on the inetaddr_chain and inet6addr_chain nfsd: Register callbacks on the inetaddr_chain and inet6addr_chain sunrpc: Add a function to close temporary transports immediately nfsd: don't base cl_cb_status on stale information nfsd4: fix gss-proxy 4.1 mounts for some AD principals nfsd: fix unlikely NULL deref in mach_creds_match nfsd: minor consolidation of mach_cred handling code nfsd: helper for dup of possibly NULL string svcrpc: move some initialization to common code nfsd: fix a warning message nfsd: constify nfsd4_callback_ops structure nfsd: recover: constify nfsd4_client_tracking_ops structures svcrdma: Do not send XDR roundup bytes for a write chunk

Linus Torvalds committed 10 years ago

Commit cc80fe02 parents c7b6c5f 6e8b50d19 files · +370 −57Browse files

Unified · Split

19 files
  1. fs/lockd/svc.c +74 −5
  2. fs/nfsd/lockd.c +1 −1
  3. fs/nfsd/netns.h +1 −1
  4. fs/nfsd/nfs4callback.c +5 −1
  5. fs/nfsd/nfs4layouts.c +27 −12
  6. fs/nfsd/nfs4recover.c +3 −3
  7. fs/nfsd/nfs4state.c +47 −18
  8. fs/nfsd/nfsfh.h +23 −0
  9. fs/nfsd/nfssvc.c +71 −4
  10. fs/nfsd/state.h +2 −2
  11. fs/nfsd/trace.h +41 −0
  12. fs/nfsd/vfs.c +15 −0
  13. include/linux/lockd/bind.h +1 −1
  14. include/linux/sunrpc/svc_xprt.h +1 −0
  15. include/linux/sunrpc/svcauth.h +8 −1
  16. net/sunrpc/auth_gss/gss_rpc_upcall.c +3 −0
  17. net/sunrpc/svc_xprt.c +45 −0
  18. net/sunrpc/svcauth.c +2 −0
  19. net/sunrpc/svcauth_unix.c +0 −8
fs/lockd/svc.c+74−5
@@ -25,13 +25,17 @@ · 24 unmodified lines
2525 #include <linux/mutex.h>
2626 #include <linux/kthread.h>
2727 #include <linux/freezer.h>
28+#include <linux/inetdevice.h>
2829
2930 #include <linux/sunrpc/types.h>
3031 #include <linux/sunrpc/stats.h>
3132 #include <linux/sunrpc/clnt.h>
3233 #include <linux/sunrpc/svc.h>
3334 #include <linux/sunrpc/svcsock.h>
35+#include <linux/sunrpc/svc_xprt.h>
3436 #include <net/ip.h>
37+#include <net/addrconf.h>
38+#include <net/ipv6.h>
3539 #include <linux/lockd/lockd.h>
3640 #include <linux/nfs.h>
3741
@@ -44,7 +48,7 @@ · 6 unmodified lines
4448
4549 static struct svc_program nlmsvc_program;
4650
47−struct nlmsvc_binding * nlmsvc_ops;
51+const struct nlmsvc_binding *nlmsvc_ops;
4852 EXPORT_SYMBOL_GPL(nlmsvc_ops);
4953
5054 static DEFINE_MUTEX(nlmsvc_mutex);
@@ -90,8 +94,7 @@ static unsigned long get_lockd_grace_period(void) · 39 unmodified lines
9094
9195 static void grace_ender(struct work_struct *grace)
9296 {
93− struct delayed_work *dwork = container_of(grace, struct delayed_work,
94− work);
97+ struct delayed_work *dwork = to_delayed_work(grace);
9598 struct lockd_net *ln = container_of(dwork, struct lockd_net,
9699 grace_period_end);
97100
@@ -279,6 +282,68 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) · 181 unmodified lines
279282 }
280283 }
281284
285+static int lockd_inetaddr_event(struct notifier_block *this,
286+ unsigned long event, void *ptr)
287+{
288+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
289+ struct sockaddr_in sin;
290+
291+ if (event != NETDEV_DOWN)
292+ goto out;
293+
294+ if (nlmsvc_rqst) {
295+ dprintk("lockd_inetaddr_event: removed %pI4\n",
296+ &ifa->ifa_local);
297+ sin.sin_family = AF_INET;
298+ sin.sin_addr.s_addr = ifa->ifa_local;
299+ svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
300+ (struct sockaddr *)&sin);
301+ }
302+
303+out:
304+ return NOTIFY_DONE;
305+}
306+
307+static struct notifier_block lockd_inetaddr_notifier = {
308+ .notifier_call = lockd_inetaddr_event,
309+};
310+
311+#if IS_ENABLED(CONFIG_IPV6)
312+static int lockd_inet6addr_event(struct notifier_block *this,
313+ unsigned long event, void *ptr)
314+{
315+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
316+ struct sockaddr_in6 sin6;
317+
318+ if (event != NETDEV_DOWN)
319+ goto out;
320+
321+ if (nlmsvc_rqst) {
322+ dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr);
323+ sin6.sin6_family = AF_INET6;
324+ sin6.sin6_addr = ifa->addr;
325+ svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
326+ (struct sockaddr *)&sin6);
327+ }
328+
329+out:
330+ return NOTIFY_DONE;
331+}
332+
333+static struct notifier_block lockd_inet6addr_notifier = {
334+ .notifier_call = lockd_inet6addr_event,
335+};
336+#endif
337+
338+static void lockd_svc_exit_thread(void)
339+{
340+ unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
341+#if IS_ENABLED(CONFIG_IPV6)
342+ unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
343+#endif
344+ svc_exit_thread(nlmsvc_rqst);
345+}
346+
282347 static int lockd_start_svc(struct svc_serv *serv)
283348 {
284349 int error;
@@ -315,7 +380,7 @@ static int lockd_start_svc(struct svc_serv *serv) · 30 unmodified lines
315380 return 0;
316381
317382 out_task:
318− svc_exit_thread(nlmsvc_rqst);
383+ lockd_svc_exit_thread();
319384 nlmsvc_task = NULL;
320385 out_rqst:
321386 nlmsvc_rqst = NULL;
@@ -360,6 +425,10 @@ static struct svc_serv *lockd_create_svc(void) · 38 unmodified lines
360425 printk(KERN_WARNING "lockd_up: create service failed\n");
361426 return ERR_PTR(-ENOMEM);
362427 }
428+ register_inetaddr_notifier(&lockd_inetaddr_notifier);
429+#if IS_ENABLED(CONFIG_IPV6)
430+ register_inet6addr_notifier(&lockd_inet6addr_notifier);
431+#endif
363432 dprintk("lockd_up: service created\n");
364433 return serv;
365434 }
@@ -428,7 +497,7 @@ lockd_down(struct net *net) · 62 unmodified lines
428497 }
429498 kthread_stop(nlmsvc_task);
430499 dprintk("lockd_down: service stopped\n");
431− svc_exit_thread(nlmsvc_rqst);
500+ lockd_svc_exit_thread();
432501 dprintk("lockd_down: service destroyed\n");
433502 nlmsvc_task = NULL;
434503 nlmsvc_rqst = NULL;
fs/nfsd/lockd.c+1−1
@@ -58,7 +58,7 @@ nlm_fclose(struct file *filp) · 57 unmodified lines
5858 fput(filp);
5959 }
6060
61−static struct nlmsvc_binding nfsd_nlm_ops = {
61+static const struct nlmsvc_binding nfsd_nlm_ops = {
6262 .fopen = nlm_fopen, /* open file for locking */
6363 .fclose = nlm_fclose, /* close file */
6464 };
fs/nfsd/netns.h+1−1
@@ -92,7 +92,7 @@ struct nfsd_net { · 91 unmodified lines
9292
9393 struct file *rec_file;
9494 bool in_grace;
95− struct nfsd4_client_tracking_ops *client_tracking_ops;
95+ const struct nfsd4_client_tracking_ops *client_tracking_ops;
9696
9797 time_t nfsd4_lease;
9898 time_t nfsd4_grace;
fs/nfsd/nfs4callback.c+5−1
@@ -792,12 +792,16 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason) · 791 unmodified lines
792792
793793 static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
794794 {
795+ if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
796+ return;
795797 clp->cl_cb_state = NFSD4_CB_DOWN;
796798 warn_no_callback_path(clp, reason);
797799 }
798800
799801 static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
800802 {
803+ if (test_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags))
804+ return;
801805 clp->cl_cb_state = NFSD4_CB_FAULT;
802806 warn_no_callback_path(clp, reason);
803807 }
@@ -1143,7 +1147,7 @@ nfsd4_run_cb_work(struct work_struct *work) · 339 unmodified lines
11431147 }
11441148
11451149 void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
1146− struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
1150+ const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
11471151 {
11481152 cb->cb_clp = clp;
11491153 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[op];
fs/nfsd/nfs4layouts.c+27−12
@@ -22,7 +22,7 @@ struct nfs4_layout { · 21 unmodified lines
2222 static struct kmem_cache *nfs4_layout_cache;
2323 static struct kmem_cache *nfs4_layout_stateid_cache;
2424
25−static struct nfsd4_callback_ops nfsd4_cb_layout_ops;
25+static const struct nfsd4_callback_ops nfsd4_cb_layout_ops;
2626 static const struct lock_manager_operations nfsd4_layouts_lm_ops;
2727
2828 const struct nfsd4_layout_ops *nfsd4_layout_ops[LAYOUT_TYPE_MAX] = {
@@ -624,24 +624,39 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) · 595 unmodified lines
624624 {
625625 struct nfs4_layout_stateid *ls =
626626 container_of(cb, struct nfs4_layout_stateid, ls_recall);
627+ struct nfsd_net *nn;
628+ ktime_t now, cutoff;
627629 LIST_HEAD(reaplist);
628630
631+
629632 switch (task->tk_status) {
630633 case 0:
631− return 1;
634+ case -NFS4ERR_DELAY:
635+ /*
636+ * Anything left? If not, then call it done. Note that we don't
637+ * take the spinlock since this is an optimization and nothing
638+ * should get added until the cb counter goes to zero.
639+ */
640+ if (list_empty(&ls->ls_layouts))
641+ return 1;
642+
643+ /* Poll the client until it's done with the layout */
644+ now = ktime_get();
645+ nn = net_generic(ls->ls_stid.sc_client->net, nfsd_net_id);
646+
647+ /* Client gets 2 lease periods to return it */
648+ cutoff = ktime_add_ns(task->tk_start,
649+ nn->nfsd4_lease * NSEC_PER_SEC * 2);
650+
651+ if (ktime_before(now, cutoff)) {
652+ rpc_delay(task, HZ/100); /* 10 mili-seconds */
653+ return 0;
654+ }
655+ /* Fallthrough */
632656 case -NFS4ERR_NOMATCHING_LAYOUT:
633657 trace_layout_recall_done(&ls->ls_stid.sc_stateid);
634658 task->tk_status = 0;
635659 return 1;
636− case -NFS4ERR_DELAY:
637− /* Poll the client until it's done with the layout */
638− /* FIXME: cap number of retries.
639− * The pnfs standard states that we need to only expire
640− * the client after at-least "lease time" .eg lease-time * 2
641− * when failing to communicate a recall
642− */
643− rpc_delay(task, HZ/100); /* 10 mili-seconds */
644− return 0;
645660 default:
646661 /*
647662 * Unknown error or non-responding client, we'll need to fence.
@@ -665,7 +680,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb) · 17 unmodified lines
665680 nfs4_put_stid(&ls->ls_stid);
666681 }
667682
668−static struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
683+static const struct nfsd4_callback_ops nfsd4_cb_layout_ops = {
669684 .prepare = nfsd4_cb_layout_prepare,
670685 .done = nfsd4_cb_layout_done,
671686 .release = nfsd4_cb_layout_release,
fs/nfsd/nfs4recover.c+3−3
@@ -631,7 +631,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp) · 630 unmodified lines
631631 return -ENOENT;
632632 }
633633
634−static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
634+static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
635635 .init = nfsd4_legacy_tracking_init,
636636 .exit = nfsd4_legacy_tracking_exit,
637637 .create = nfsd4_create_clid_dir,
@@ -1050,7 +1050,7 @@ out_err: · 412 unmodified lines
10501050 printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
10511051 }
10521052
1053−static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
1053+static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
10541054 .init = nfsd4_init_cld_pipe,
10551055 .exit = nfsd4_remove_cld_pipe,
10561056 .create = nfsd4_cld_create,
@@ -1394,7 +1394,7 @@ nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn) · 337 unmodified lines
13941394 kfree(legacy);
13951395 }
13961396
1397−static struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
1397+static const struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
13981398 .init = nfsd4_umh_cltrack_init,
13991399 .exit = NULL,
14001400 .create = nfsd4_umh_cltrack_create,
fs/nfsd/nfs4state.c+47−18
@@ -98,7 +98,7 @@ static struct kmem_cache *odstate_slab; · 97 unmodified lines
9898
9999 static void free_session(struct nfsd4_session *);
100100
101−static struct nfsd4_callback_ops nfsd4_cb_recall_ops;
101+static const struct nfsd4_callback_ops nfsd4_cb_recall_ops;
102102
103103 static bool is_session_dead(struct nfsd4_session *ses)
104104 {
@@ -1857,15 +1857,28 @@ static void copy_clid(struct nfs4_client *target, struct nfs4_client *source) · 1752 unmodified lines
18571857 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
18581858 }
18591859
1860−static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1860+int strdup_if_nonnull(char **target, char *source)
18611861 {
1862− if (source->cr_principal) {
1863− target->cr_principal =
1864− kstrdup(source->cr_principal, GFP_KERNEL);
1865− if (target->cr_principal == NULL)
1862+ if (source) {
1863+ *target = kstrdup(source, GFP_KERNEL);
1864+ if (!*target)
18661865 return -ENOMEM;
18671866 } else
1868− target->cr_principal = NULL;
1867+ *target = NULL;
1868+ return 0;
1869+}
1870+
1871+static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1872+{
1873+ int ret;
1874+
1875+ ret = strdup_if_nonnull(&target->cr_principal, source->cr_principal);
1876+ if (ret)
1877+ return ret;
1878+ ret = strdup_if_nonnull(&target->cr_raw_principal,
1879+ source->cr_raw_principal);
1880+ if (ret)
1881+ return ret;
18691882 target->cr_flavor = source->cr_flavor;
18701883 target->cr_uid = source->cr_uid;
18711884 target->cr_gid = source->cr_gid;
@@ -1969,6 +1982,9 @@ static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp) · 97 unmodified lines
19691982 return false;
19701983 if (!svc_rqst_integrity_protected(rqstp))
19711984 return false;
1985+ if (cl->cl_cred.cr_raw_principal)
1986+ return 0 == strcmp(cl->cl_cred.cr_raw_principal,
1987+ cr->cr_raw_principal);
19721988 if (!cr->cr_principal)
19731989 return false;
19741990 return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal);
@@ -2240,7 +2256,8 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) · 265 unmodified lines
22402256 base = resp->cstate.data_offset;
22412257 slot->sl_datalen = buf->len - base;
22422258 if (read_bytes_from_xdr_buf(buf, base, slot->sl_data, slot->sl_datalen))
2243− WARN("%s: sessions DRC could not cache compound\n", __func__);
2259+ WARN(1, "%s: sessions DRC could not cache compound\n",
2260+ __func__);
22442261 return;
22452262 }
22462263
@@ -2365,10 +2382,27 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, · 118 unmodified lines
23652382 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
23662383 return nfserr_inval;
23672384
2385+ new = create_client(exid->clname, rqstp, &verf);
2386+ if (new == NULL)
2387+ return nfserr_jukebox;
2388+
23682389 switch (exid->spa_how) {
23692390 case SP4_MACH_CRED:
2370− if (!svc_rqst_integrity_protected(rqstp))
2371− return nfserr_inval;
2391+ if (!svc_rqst_integrity_protected(rqstp)) {
2392+ status = nfserr_inval;
2393+ goto out_nolock;
2394+ }
2395+ /*
2396+ * Sometimes userspace doesn't give us a principal.
2397+ * Which is a bug, really. Anyway, we can't enforce
2398+ * MACH_CRED in that case, better to give up now:
2399+ */
2400+ if (!new->cl_cred.cr_principal &&
2401+ !new->cl_cred.cr_raw_principal) {
2402+ status = nfserr_serverfault;
2403+ goto out_nolock;
2404+ }
2405+ new->cl_mach_cred = true;
23722406 case SP4_NONE:
23732407 break;
23742408 default: /* checked by xdr code */
@@ -2377,10 +2411,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, · 2 unmodified lines
23772411 return nfserr_encr_alg_unsupp;
23782412 }
23792413
2380− new = create_client(exid->clname, rqstp, &verf);
2381− if (new == NULL)
2382− return nfserr_jukebox;
2383−
23842414 /* Cases below refer to rfc 5661 section 18.35.4: */
23852415 spin_lock(&nn->client_lock);
23862416 conf = find_confirmed_client_by_name(&exid->clname, nn);
@@ -2442,7 +2472,6 @@ out_new: · 55 unmodified lines
24422472 goto out;
24432473 }
24442474 new->cl_minorversion = cstate->minorversion;
2445− new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
24462475
24472476 gen_clid(new, nn);
24482477 add_to_unconfirmed(new);
@@ -2460,6 +2489,7 @@ out_copy: · 11 unmodified lines
24602489
24612490 out:
24622491 spin_unlock(&nn->client_lock);
2492+out_nolock:
24632493 if (new)
24642494 expire_client(new);
24652495 if (unconf)
@@ -3648,7 +3678,7 @@ static void nfsd4_cb_recall_release(struct nfsd4_callback *cb) · 1182 unmodified lines
36483678 nfs4_put_stid(&dp->dl_stid);
36493679 }
36503680
3651−static struct nfsd4_callback_ops nfsd4_cb_recall_ops = {
3681+static const struct nfsd4_callback_ops nfsd4_cb_recall_ops = {
36523682 .prepare = nfsd4_cb_recall_prepare,
36533683 .done = nfsd4_cb_recall_done,
36543684 .release = nfsd4_cb_recall_release,
@@ -4541,8 +4571,7 @@ static void · 886 unmodified lines
45414571 laundromat_main(struct work_struct *laundry)
45424572 {
45434573 time_t t;
4544− struct delayed_work *dwork = container_of(laundry, struct delayed_work,
4545− work);
4574+ struct delayed_work *dwork = to_delayed_work(laundry);
45464575 struct nfsd_net *nn = container_of(dwork, struct nfsd_net,
45474576 laundromat_work);
45484577
fs/nfsd/nfsfh.h+23−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #ifndef _LINUX_NFSD_NFSFH_H
88 #define _LINUX_NFSD_NFSFH_H
99
10+#include <linux/crc32.h>
1011 #include <linux/sunrpc/svc.h>
1112 #include <uapi/linux/nfsd/nfsfh.h>
1213
@@ -205,6 +206,28 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) · 192 unmodified lines
205206 return true;
206207 }
207208
209+#ifdef CONFIG_CRC32
210+/**
211+ * knfsd_fh_hash - calculate the crc32 hash for the filehandle
212+ * @fh - pointer to filehandle
213+ *
214+ * returns a crc32 hash for the filehandle that is compatible with
215+ * the one displayed by "wireshark".
216+ */
217+
218+static inline u32
219+knfsd_fh_hash(struct knfsd_fh *fh)
220+{
221+ return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size);
222+}
223+#else
224+static inline u32
225+knfsd_fh_hash(struct knfsd_fh *fh)
226+{
227+ return 0;
228+}
229+#endif
230+
208231 #ifdef CONFIG_NFSD_V3
209232 /*
210233 * The wcc data stored in current_fh should be cleared
fs/nfsd/nfssvc.c+71−4
@@ -14,9 +14,13 @@ · 13 unmodified lines
1414
1515 #include <linux/sunrpc/stats.h>
1616 #include <linux/sunrpc/svcsock.h>
17+#include <linux/sunrpc/svc_xprt.h>
1718 #include <linux/lockd/bind.h>
1819 #include <linux/nfsacl.h>
1920 #include <linux/seq_file.h>
21+#include <linux/inetdevice.h>
22+#include <net/addrconf.h>
23+#include <net/ipv6.h>
2024 #include <net/net_namespace.h>
2125 #include "nfsd.h"
2226 #include "cache.h"
@@ -306,22 +310,81 @@ static void nfsd_shutdown_net(struct net *net) · 283 unmodified lines
306310 nfsd_shutdown_generic();
307311 }
308312
313+static int nfsd_inetaddr_event(struct notifier_block *this, unsigned long event,
314+ void *ptr)
315+{
316+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
317+ struct net_device *dev = ifa->ifa_dev->dev;
318+ struct net *net = dev_net(dev);
319+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
320+ struct sockaddr_in sin;
321+
322+ if (event != NETDEV_DOWN)
323+ goto out;
324+
325+ if (nn->nfsd_serv) {
326+ dprintk("nfsd_inetaddr_event: removed %pI4\n", &ifa->ifa_local);
327+ sin.sin_family = AF_INET;
328+ sin.sin_addr.s_addr = ifa->ifa_local;
329+ svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin);
330+ }
331+
332+out:
333+ return NOTIFY_DONE;
334+}
335+
336+static struct notifier_block nfsd_inetaddr_notifier = {
337+ .notifier_call = nfsd_inetaddr_event,
338+};
339+
340+#if IS_ENABLED(CONFIG_IPV6)
341+static int nfsd_inet6addr_event(struct notifier_block *this,
342+ unsigned long event, void *ptr)
343+{
344+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
345+ struct net_device *dev = ifa->idev->dev;
346+ struct net *net = dev_net(dev);
347+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
348+ struct sockaddr_in6 sin6;
349+
350+ if (event != NETDEV_DOWN)
351+ goto out;
352+
353+ if (nn->nfsd_serv) {
354+ dprintk("nfsd_inet6addr_event: removed %pI6\n", &ifa->addr);
355+ sin6.sin6_family = AF_INET6;
356+ sin6.sin6_addr = ifa->addr;
357+ svc_age_temp_xprts_now(nn->nfsd_serv, (struct sockaddr *)&sin6);
358+ }
359+
360+out:
361+ return NOTIFY_DONE;
362+}
363+
364+static struct notifier_block nfsd_inet6addr_notifier = {
365+ .notifier_call = nfsd_inet6addr_event,
366+};
367+#endif
368+
309369 static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
310370 {
311371 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
312372
373+ unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
374+#if IS_ENABLED(CONFIG_IPV6)
375+ unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
376+#endif
313377 /*
314378 * write_ports can create the server without actually starting
315379 * any threads--if we get shut down before any threads are
316380 * started, then nfsd_last_thread will be run before any of this
317− * other initialization has been done.
381+ * other initialization has been done except the rpcb information.
318382 */
383+ svc_rpcb_cleanup(serv, net);
319384 if (!nn->nfsd_net_up)
320385 return;
321− nfsd_shutdown_net(net);
322−
323− svc_rpcb_cleanup(serv, net);
324386
387+ nfsd_shutdown_net(net);
325388 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
326389 "cache\n");
327390 nfsd_export_flush(net);
@@ -425,6 +488,10 @@ int nfsd_create_serv(struct net *net) · 97 unmodified lines
425488 }
426489
427490 set_max_drc();
491+ register_inetaddr_notifier(&nfsd_inetaddr_notifier);
492+#if IS_ENABLED(CONFIG_IPV6)
493+ register_inet6addr_notifier(&nfsd_inet6addr_notifier);
494+#endif
428495 do_gettimeofday(&nn->nfssvc_boot); /* record boot time */
429496 return 0;
430497 }
fs/nfsd/state.h+2−2
@@ -65,7 +65,7 @@ struct nfsd4_callback { · 64 unmodified lines
6565 struct nfs4_client *cb_clp;
6666 u32 cb_minorversion;
6767 struct rpc_message cb_msg;
68− struct nfsd4_callback_ops *cb_ops;
68+ const struct nfsd4_callback_ops *cb_ops;
6969 struct work_struct cb_work;
7070 int cb_seq_status;
7171 int cb_status;
@@ -599,7 +599,7 @@ extern void nfsd4_probe_callback(struct nfs4_client *clp); · 527 unmodified lines
599599 extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
600600 extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
601601 extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
602− struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
602+ const struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
603603 extern void nfsd4_run_cb(struct nfsd4_callback *cb);
604604 extern int nfsd4_create_callback_queue(void);
605605 extern void nfsd4_destroy_callback_queue(void);
fs/nfsd/trace.h+41−0
@@ -8,6 +8,47 @@ · 7 unmodified lines
88 #define _NFSD_TRACE_H
99
1010 #include <linux/tracepoint.h>
11+#include "nfsfh.h"
12+
13+DECLARE_EVENT_CLASS(nfsd_io_class,
14+ TP_PROTO(struct svc_rqst *rqstp,
15+ struct svc_fh *fhp,
16+ loff_t offset,
17+ int len),
18+ TP_ARGS(rqstp, fhp, offset, len),
19+ TP_STRUCT__entry(
20+ __field(__be32, xid)
21+ __field_struct(struct knfsd_fh, fh)
22+ __field(loff_t, offset)
23+ __field(int, len)
24+ ),
25+ TP_fast_assign(
26+ __entry->xid = rqstp->rq_xid,
27+ fh_copy_shallow(&__entry->fh, &fhp->fh_handle);
28+ __entry->offset = offset;
29+ __entry->len = len;
30+ ),
31+ TP_printk("xid=0x%x fh=0x%x offset=%lld len=%d",
32+ __be32_to_cpu(__entry->xid), knfsd_fh_hash(&__entry->fh),
33+ __entry->offset, __entry->len)
34+)
35+
36+#define DEFINE_NFSD_IO_EVENT(name) \
37+DEFINE_EVENT(nfsd_io_class, name, \
38+ TP_PROTO(struct svc_rqst *rqstp, \
39+ struct svc_fh *fhp, \
40+ loff_t offset, \
41+ int len), \
42+ TP_ARGS(rqstp, fhp, offset, len))
43+
44+DEFINE_NFSD_IO_EVENT(read_start);
45+DEFINE_NFSD_IO_EVENT(read_opened);
46+DEFINE_NFSD_IO_EVENT(read_io_done);
47+DEFINE_NFSD_IO_EVENT(read_done);
48+DEFINE_NFSD_IO_EVENT(write_start);
49+DEFINE_NFSD_IO_EVENT(write_opened);
50+DEFINE_NFSD_IO_EVENT(write_io_done);
51+DEFINE_NFSD_IO_EVENT(write_done);
1152
1253 #include "state.h"
1354
fs/nfsd/vfs.c+15−0
@@ -43,6 +43,7 @@ · 42 unmodified lines
4343
4444 #include "nfsd.h"
4545 #include "vfs.h"
46+#include "trace.h"
4647
4748 #define NFSDDBG_FACILITY NFSDDBG_FILEOP
4849
@@ -997,16 +998,23 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, · 948 unmodified lines
997998 struct raparms *ra;
998999 __be32 err;
9991000
1001+ trace_read_start(rqstp, fhp, offset, vlen);
10001002 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
10011003 if (err)
10021004 return err;
10031005
10041006 ra = nfsd_init_raparms(file);
1007+
1008+ trace_read_opened(rqstp, fhp, offset, vlen);
10051009 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
1010+ trace_read_io_done(rqstp, fhp, offset, vlen);
1011+
10061012 if (ra)
10071013 nfsd_put_raparams(file, ra);
10081014 fput(file);
10091015
1016+ trace_read_done(rqstp, fhp, offset, vlen);
1017+
10101018 return err;
10111019 }
10121020
@@ -1022,24 +1030,31 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, · 9 unmodified lines
10221030 {
10231031 __be32 err = 0;
10241032
1033+ trace_write_start(rqstp, fhp, offset, vlen);
1034+
10251035 if (file) {
10261036 err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
10271037 NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE);
10281038 if (err)
10291039 goto out;
1040+ trace_write_opened(rqstp, fhp, offset, vlen);
10301041 err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt,
10311042 stablep);
1043+ trace_write_io_done(rqstp, fhp, offset, vlen);
10321044 } else {
10331045 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
10341046 if (err)
10351047 goto out;
10361048
1049+ trace_write_opened(rqstp, fhp, offset, vlen);
10371050 if (cnt)
10381051 err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen,
10391052 cnt, stablep);
1053+ trace_write_io_done(rqstp, fhp, offset, vlen);
10401054 fput(file);
10411055 }
10421056 out:
1057+ trace_write_done(rqstp, fhp, offset, vlen);
10431058 return err;
10441059 }
10451060
include/linux/lockd/bind.h+1−1
@@ -29,7 +29,7 @@ struct nlmsvc_binding { · 28 unmodified lines
2929 void (*fclose)(struct file *);
3030 };
3131
32−extern struct nlmsvc_binding * nlmsvc_ops;
32+extern const struct nlmsvc_binding *nlmsvc_ops;
3333
3434 /*
3535 * Similar to nfs_client_initdata, but without the NFS-specific
include/linux/sunrpc/svc_xprt.h+1−0
@@ -128,6 +128,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, · 127 unmodified lines
128128 const unsigned short port);
129129 int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
130130 void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt);
131+void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *);
131132
132133 static inline void svc_xprt_get(struct svc_xprt *xprt)
133134 {
include/linux/sunrpc/svcauth.h+8−1
@@ -23,13 +23,19 @@ struct svc_cred { · 22 unmodified lines
2323 kgid_t cr_gid;
2424 struct group_info *cr_group_info;
2525 u32 cr_flavor; /* pseudoflavor */
26− char *cr_principal; /* for gss */
26+ /* name of form servicetype/hostname@REALM, passed down by
27+ * gss-proxy: */
28+ char *cr_raw_principal;
29+ /* name of form servicetype@hostname, passed down by
30+ * rpc.svcgssd, or computed from the above: */
31+ char *cr_principal;
2732 struct gss_api_mech *cr_gss_mech;
2833 };
2934
3035 static inline void init_svc_cred(struct svc_cred *cred)
3136 {
3237 cred->cr_group_info = NULL;
38+ cred->cr_raw_principal = NULL;
3339 cred->cr_principal = NULL;
3440 cred->cr_gss_mech = NULL;
3541 }
@@ -38,6 +44,7 @@ static inline void free_svc_cred(struct svc_cred *cred) · 2 unmodified lines
3844 {
3945 if (cred->cr_group_info)
4046 put_group_info(cred->cr_group_info);
47+ kfree(cred->cr_raw_principal);
4148 kfree(cred->cr_principal);
4249 gss_mech_put(cred->cr_gss_mech);
4350 init_svc_cred(cred);
net/sunrpc/auth_gss/gss_rpc_upcall.c+3−0
@@ -326,6 +326,9 @@ int gssp_accept_sec_context_upcall(struct net *net, · 325 unmodified lines
326326 if (data->found_creds && client_name.data != NULL) {
327327 char *c;
328328
329+ data->creds.cr_raw_principal = kstrndup(client_name.data,
330+ client_name.len, GFP_KERNEL);
331+
329332 data->creds.cr_principal = kstrndup(client_name.data,
330333 client_name.len, GFP_KERNEL);
331334 if (data->creds.cr_principal) {
net/sunrpc/svc_xprt.c+45−0
@@ -10,11 +10,13 @@ · 9 unmodified lines
1010 #include <linux/kthread.h>
1111 #include <linux/slab.h>
1212 #include <net/sock.h>
13+#include <linux/sunrpc/addr.h>
1314 #include <linux/sunrpc/stats.h>
1415 #include <linux/sunrpc/svc_xprt.h>
1516 #include <linux/sunrpc/svcsock.h>
1617 #include <linux/sunrpc/xprt.h>
1718 #include <linux/module.h>
19+#include <linux/netdevice.h>
1820 #include <trace/events/sunrpc.h>
1921
2022 #define RPCDBG_FACILITY RPCDBG_SVCXPRT
@@ -938,6 +940,49 @@ static void svc_age_temp_xprts(unsigned long closure) · 917 unmodified lines
938940 mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
939941 }
940942
943+/* Close temporary transports whose xpt_local matches server_addr immediately
944+ * instead of waiting for them to be picked up by the timer.
945+ *
946+ * This is meant to be called from a notifier_block that runs when an ip
947+ * address is deleted.
948+ */
949+void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
950+{
951+ struct svc_xprt *xprt;
952+ struct svc_sock *svsk;
953+ struct socket *sock;
954+ struct list_head *le, *next;
955+ LIST_HEAD(to_be_closed);
956+ struct linger no_linger = {
957+ .l_onoff = 1,
958+ .l_linger = 0,
959+ };
960+
961+ spin_lock_bh(&serv->sv_lock);
962+ list_for_each_safe(le, next, &serv->sv_tempsocks) {
963+ xprt = list_entry(le, struct svc_xprt, xpt_list);
964+ if (rpc_cmp_addr(server_addr, (struct sockaddr *)
965+ &xprt->xpt_local)) {
966+ dprintk("svc_age_temp_xprts_now: found %p\n", xprt);
967+ list_move(le, &to_be_closed);
968+ }
969+ }
970+ spin_unlock_bh(&serv->sv_lock);
971+
972+ while (!list_empty(&to_be_closed)) {
973+ le = to_be_closed.next;
974+ list_del_init(le);
975+ xprt = list_entry(le, struct svc_xprt, xpt_list);
976+ dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
977+ svsk = container_of(xprt, struct svc_sock, sk_xprt);
978+ sock = svsk->sk_sock;
979+ kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
980+ (char *)&no_linger, sizeof(no_linger));
981+ svc_close_xprt(xprt);
982+ }
983+}
984+EXPORT_SYMBOL_GPL(svc_age_temp_xprts_now);
985+
941986 static void call_xpt_users(struct svc_xprt *xprt)
942987 {
943988 struct svc_xpt_user *u;
net/sunrpc/svcauth.c+2−0
@@ -55,6 +55,7 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) · 54 unmodified lines
5555 spin_unlock(&authtab_lock);
5656
5757 rqstp->rq_auth_slack = 0;
58+ init_svc_cred(&rqstp->rq_cred);
5859
5960 rqstp->rq_authop = aops;
6061 return aops->accept(rqstp, authp);
@@ -63,6 +64,7 @@ EXPORT_SYMBOL_GPL(svc_authenticate); · 2 unmodified lines
6364
6465 int svc_set_client(struct svc_rqst *rqstp)
6566 {
67+ rqstp->rq_client = NULL;
6668 return rqstp->rq_authop->set_client(rqstp);
6769 }
6870 EXPORT_SYMBOL_GPL(svc_set_client);
net/sunrpc/svcauth_unix.c+0−8
@@ -728,10 +728,6 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) · 727 unmodified lines
728728 struct kvec *resv = &rqstp->rq_res.head[0];
729729 struct svc_cred *cred = &rqstp->rq_cred;
730730
731− cred->cr_group_info = NULL;
732− cred->cr_principal = NULL;
733− rqstp->rq_client = NULL;
734−
735731 if (argv->iov_len < 3*4)
736732 return SVC_GARBAGE;
737733
@@ -794,10 +790,6 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) · 56 unmodified lines
794790 u32 slen, i;
795791 int len = argv->iov_len;
796792
797− cred->cr_group_info = NULL;
798− cred->cr_principal = NULL;
799− rqstp->rq_client = NULL;
800−
801793 if ((len -= 3*4) < 0)
802794 return SVC_GARBAGE;
803795