Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'nfs-for-4.8-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:

- Stable patch from Olga to fix RPCSEC_GSS upcalls when the same user
needs multiple different security services (e.g. krb5i and krb5p).

- Stable patch to fix a regression introduced by the use of
SO_REUSEPORT, and that prevented the use of multiple different NFS
versions to the same server.

- TCP socket reconnection timer fixes.

- Patch from Neil to disable the use of IPv6 temporary addresses"

* tag 'nfs-for-4.8-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv4: Cap the transport reconnection timer at 1/2 lease period
NFSv4: Cleanup the setting of the nfs4 lease period
SUNRPC: Limit the reconnect backoff timer to the max RPC message timeout
SUNRPC: Fix reconnection timeouts
NFSv4.2: LAYOUTSTATS may return NFS4ERR_ADMIN/DELEG_REVOKED
SUNRPC: disable the use of IPv6 temporary addresses.
SUNRPC: allow for upcalls for same uid but different gss service
SUNRPC: Fix up socket autodisconnect
SUNRPC: Handle EADDRNOTAVAIL on connection failures

+130 -37
+2
fs/nfs/nfs42proc.c
··· 338 338 case 0: 339 339 break; 340 340 case -NFS4ERR_EXPIRED: 341 + case -NFS4ERR_ADMIN_REVOKED: 342 + case -NFS4ERR_DELEG_REVOKED: 341 343 case -NFS4ERR_STALE_STATEID: 342 344 case -NFS4ERR_OLD_STATEID: 343 345 case -NFS4ERR_BAD_STATEID:
+4
fs/nfs/nfs4_fs.h
··· 396 396 extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); 397 397 extern void nfs4_kill_renewd(struct nfs_client *); 398 398 extern void nfs4_renew_state(struct work_struct *); 399 + extern void nfs4_set_lease_period(struct nfs_client *clp, 400 + unsigned long lease, 401 + unsigned long lastrenewed); 402 + 399 403 400 404 /* nfs4state.c */ 401 405 struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp);
+3 -6
fs/nfs/nfs4proc.c
··· 4237 4237 err = _nfs4_do_fsinfo(server, fhandle, fsinfo); 4238 4238 trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err); 4239 4239 if (err == 0) { 4240 - struct nfs_client *clp = server->nfs_client; 4241 - 4242 - spin_lock(&clp->cl_lock); 4243 - clp->cl_lease_time = fsinfo->lease_time * HZ; 4244 - clp->cl_last_renewal = now; 4245 - spin_unlock(&clp->cl_lock); 4240 + nfs4_set_lease_period(server->nfs_client, 4241 + fsinfo->lease_time * HZ, 4242 + now); 4246 4243 break; 4247 4244 } 4248 4245 err = nfs4_handle_exception(server, err, &exception);
+20
fs/nfs/nfs4renewd.c
··· 136 136 cancel_delayed_work_sync(&clp->cl_renewd); 137 137 } 138 138 139 + /** 140 + * nfs4_set_lease_period - Sets the lease period on a nfs_client 141 + * 142 + * @clp: pointer to nfs_client 143 + * @lease: new value for lease period 144 + * @lastrenewed: time at which lease was last renewed 145 + */ 146 + void nfs4_set_lease_period(struct nfs_client *clp, 147 + unsigned long lease, 148 + unsigned long lastrenewed) 149 + { 150 + spin_lock(&clp->cl_lock); 151 + clp->cl_lease_time = lease; 152 + clp->cl_last_renewal = lastrenewed; 153 + spin_unlock(&clp->cl_lock); 154 + 155 + /* Cap maximum reconnect timeout at 1/2 lease period */ 156 + rpc_cap_max_reconnect_timeout(clp->cl_rpcclient, lease >> 1); 157 + } 158 + 139 159 /* 140 160 * Local variables: 141 161 * c-basic-offset: 8
+3 -6
fs/nfs/nfs4state.c
··· 277 277 { 278 278 int status; 279 279 struct nfs_fsinfo fsinfo; 280 + unsigned long now; 280 281 281 282 if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) { 282 283 nfs4_schedule_state_renewal(clp); 283 284 return 0; 284 285 } 285 286 287 + now = jiffies; 286 288 status = nfs4_proc_get_lease_time(clp, &fsinfo); 287 289 if (status == 0) { 288 - /* Update lease time and schedule renewal */ 289 - spin_lock(&clp->cl_lock); 290 - clp->cl_lease_time = fsinfo.lease_time * HZ; 291 - clp->cl_last_renewal = jiffies; 292 - spin_unlock(&clp->cl_lock); 293 - 290 + nfs4_set_lease_period(clp, fsinfo.lease_time * HZ, now); 294 291 nfs4_schedule_state_renewal(clp); 295 292 } 296 293
+2
include/linux/sunrpc/clnt.h
··· 195 195 struct rpc_xprt *, 196 196 void *), 197 197 void *data); 198 + void rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, 199 + unsigned long timeo); 198 200 199 201 const char *rpc_proc_name(const struct rpc_task *task); 200 202 #endif /* __KERNEL__ */
+2 -1
include/linux/sunrpc/xprt.h
··· 218 218 struct work_struct task_cleanup; 219 219 struct timer_list timer; 220 220 unsigned long last_used, 221 - idle_timeout; 221 + idle_timeout, 222 + max_reconnect_timeout; 222 223 223 224 /* 224 225 * Send stuff
+5 -3
net/sunrpc/auth_gss/auth_gss.c
··· 340 340 } 341 341 342 342 static struct gss_upcall_msg * 343 - __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid) 343 + __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth) 344 344 { 345 345 struct gss_upcall_msg *pos; 346 346 list_for_each_entry(pos, &pipe->in_downcall, list) { 347 347 if (!uid_eq(pos->uid, uid)) 348 + continue; 349 + if (auth && pos->auth->service != auth->service) 348 350 continue; 349 351 atomic_inc(&pos->count); 350 352 dprintk("RPC: %s found msg %p\n", __func__, pos); ··· 367 365 struct gss_upcall_msg *old; 368 366 369 367 spin_lock(&pipe->lock); 370 - old = __gss_find_upcall(pipe, gss_msg->uid); 368 + old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth); 371 369 if (old == NULL) { 372 370 atomic_inc(&gss_msg->count); 373 371 list_add(&gss_msg->list, &pipe->in_downcall); ··· 716 714 err = -ENOENT; 717 715 /* Find a matching upcall */ 718 716 spin_lock(&pipe->lock); 719 - gss_msg = __gss_find_upcall(pipe, uid); 717 + gss_msg = __gss_find_upcall(pipe, uid, NULL); 720 718 if (gss_msg == NULL) { 721 719 spin_unlock(&pipe->lock); 722 720 goto err_put_ctx;
+24
net/sunrpc/clnt.c
··· 2638 2638 { 2639 2639 struct rpc_xprt_switch *xps; 2640 2640 struct rpc_xprt *xprt; 2641 + unsigned long reconnect_timeout; 2641 2642 unsigned char resvport; 2642 2643 int ret = 0; 2643 2644 ··· 2650 2649 return -EAGAIN; 2651 2650 } 2652 2651 resvport = xprt->resvport; 2652 + reconnect_timeout = xprt->max_reconnect_timeout; 2653 2653 rcu_read_unlock(); 2654 2654 2655 2655 xprt = xprt_create_transport(xprtargs); ··· 2659 2657 goto out_put_switch; 2660 2658 } 2661 2659 xprt->resvport = resvport; 2660 + xprt->max_reconnect_timeout = reconnect_timeout; 2662 2661 2663 2662 rpc_xprt_switch_set_roundrobin(xps); 2664 2663 if (setup) { ··· 2675 2672 return ret; 2676 2673 } 2677 2674 EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); 2675 + 2676 + static int 2677 + rpc_xprt_cap_max_reconnect_timeout(struct rpc_clnt *clnt, 2678 + struct rpc_xprt *xprt, 2679 + void *data) 2680 + { 2681 + unsigned long timeout = *((unsigned long *)data); 2682 + 2683 + if (timeout < xprt->max_reconnect_timeout) 2684 + xprt->max_reconnect_timeout = timeout; 2685 + return 0; 2686 + } 2687 + 2688 + void 2689 + rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, unsigned long timeo) 2690 + { 2691 + rpc_clnt_iterate_for_each_xprt(clnt, 2692 + rpc_xprt_cap_max_reconnect_timeout, 2693 + &timeo); 2694 + } 2695 + EXPORT_SYMBOL_GPL(rpc_cap_max_reconnect_timeout); 2678 2696 2679 2697 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 2680 2698 static void rpc_show_header(void)
+18 -8
net/sunrpc/xprt.c
··· 680 680 spin_unlock_bh(&xprt->transport_lock); 681 681 } 682 682 683 + static bool 684 + xprt_has_timer(const struct rpc_xprt *xprt) 685 + { 686 + return xprt->idle_timeout != 0; 687 + } 688 + 689 + static void 690 + xprt_schedule_autodisconnect(struct rpc_xprt *xprt) 691 + __must_hold(&xprt->transport_lock) 692 + { 693 + if (list_empty(&xprt->recv) && xprt_has_timer(xprt)) 694 + mod_timer(&xprt->timer, xprt->last_used + xprt->idle_timeout); 695 + } 696 + 683 697 static void 684 698 xprt_init_autodisconnect(unsigned long data) 685 699 { ··· 702 688 spin_lock(&xprt->transport_lock); 703 689 if (!list_empty(&xprt->recv)) 704 690 goto out_abort; 691 + /* Reset xprt->last_used to avoid connect/autodisconnect cycling */ 692 + xprt->last_used = jiffies; 705 693 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) 706 694 goto out_abort; 707 695 spin_unlock(&xprt->transport_lock); ··· 741 725 goto out; 742 726 xprt->snd_task =NULL; 743 727 xprt->ops->release_xprt(xprt, NULL); 728 + xprt_schedule_autodisconnect(xprt); 744 729 out: 745 730 spin_unlock_bh(&xprt->transport_lock); 746 731 wake_up_bit(&xprt->state, XPRT_LOCKED); ··· 903 886 } else 904 887 task->tk_status = 0; 905 888 spin_unlock_bh(&xprt->transport_lock); 906 - } 907 - 908 - static inline int xprt_has_timer(struct rpc_xprt *xprt) 909 - { 910 - return xprt->idle_timeout != 0; 911 889 } 912 890 913 891 /** ··· 1292 1280 if (!list_empty(&req->rq_list)) 1293 1281 list_del(&req->rq_list); 1294 1282 xprt->last_used = jiffies; 1295 - if (list_empty(&xprt->recv) && xprt_has_timer(xprt)) 1296 - mod_timer(&xprt->timer, 1297 - xprt->last_used + xprt->idle_timeout); 1283 + xprt_schedule_autodisconnect(xprt); 1298 1284 spin_unlock_bh(&xprt->transport_lock); 1299 1285 if (req->rq_buffer) 1300 1286 xprt->ops->buf_free(req->rq_buffer);
+47 -13
net/sunrpc/xprtsock.c
··· 177 177 * increase over time if the server is down or not responding. 178 178 */ 179 179 #define XS_TCP_INIT_REEST_TO (3U * HZ) 180 - #define XS_TCP_MAX_REEST_TO (5U * 60 * HZ) 181 180 182 181 /* 183 182 * TCP idle timeout; client drops the transport socket if it is idle ··· 2172 2173 write_unlock_bh(&sk->sk_callback_lock); 2173 2174 } 2174 2175 xs_udp_do_set_buffer_size(xprt); 2176 + 2177 + xprt->stat.connect_start = jiffies; 2175 2178 } 2176 2179 2177 2180 static void xs_udp_setup_socket(struct work_struct *work) ··· 2237 2236 unsigned int keepcnt = xprt->timeout->to_retries + 1; 2238 2237 unsigned int opt_on = 1; 2239 2238 unsigned int timeo; 2239 + unsigned int addr_pref = IPV6_PREFER_SRC_PUBLIC; 2240 2240 2241 2241 /* TCP Keepalive options */ 2242 2242 kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, ··· 2248 2246 (char *)&keepidle, sizeof(keepidle)); 2249 2247 kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT, 2250 2248 (char *)&keepcnt, sizeof(keepcnt)); 2249 + 2250 + /* Avoid temporary address, they are bad for long-lived 2251 + * connections such as NFS mounts. 2252 + * RFC4941, section 3.6 suggests that: 2253 + * Individual applications, which have specific 2254 + * knowledge about the normal duration of connections, 2255 + * MAY override this as appropriate. 2256 + */ 2257 + kernel_setsockopt(sock, SOL_IPV6, IPV6_ADDR_PREFERENCES, 2258 + (char *)&addr_pref, sizeof(addr_pref)); 2251 2259 2252 2260 /* TCP user timeout (see RFC5482) */ 2253 2261 timeo = jiffies_to_msecs(xprt->timeout->to_initval) * ··· 2307 2295 /* SYN_SENT! */ 2308 2296 if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) 2309 2297 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 2298 + break; 2299 + case -EADDRNOTAVAIL: 2300 + /* Source port number is unavailable. Try a new one! */ 2301 + transport->srcport = 0; 2310 2302 } 2311 2303 out: 2312 2304 return ret; ··· 2385 2369 xprt_wake_pending_tasks(xprt, status); 2386 2370 } 2387 2371 2372 + static unsigned long xs_reconnect_delay(const struct rpc_xprt *xprt) 2373 + { 2374 + unsigned long start, now = jiffies; 2375 + 2376 + start = xprt->stat.connect_start + xprt->reestablish_timeout; 2377 + if (time_after(start, now)) 2378 + return start - now; 2379 + return 0; 2380 + } 2381 + 2382 + static void xs_reconnect_backoff(struct rpc_xprt *xprt) 2383 + { 2384 + xprt->reestablish_timeout <<= 1; 2385 + if (xprt->reestablish_timeout > xprt->max_reconnect_timeout) 2386 + xprt->reestablish_timeout = xprt->max_reconnect_timeout; 2387 + if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) 2388 + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 2389 + } 2390 + 2388 2391 /** 2389 2392 * xs_connect - connect a socket to a remote endpoint 2390 2393 * @xprt: pointer to transport structure ··· 2421 2386 static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task) 2422 2387 { 2423 2388 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 2389 + unsigned long delay = 0; 2424 2390 2425 2391 WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport)); 2426 2392 ··· 2433 2397 /* Start by resetting any existing state */ 2434 2398 xs_reset_transport(transport); 2435 2399 2436 - queue_delayed_work(xprtiod_workqueue, 2437 - &transport->connect_worker, 2438 - xprt->reestablish_timeout); 2439 - xprt->reestablish_timeout <<= 1; 2440 - if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) 2441 - xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 2442 - if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) 2443 - xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; 2444 - } else { 2400 + delay = xs_reconnect_delay(xprt); 2401 + xs_reconnect_backoff(xprt); 2402 + 2403 + } else 2445 2404 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); 2446 - queue_delayed_work(xprtiod_workqueue, 2447 - &transport->connect_worker, 0); 2448 - } 2405 + 2406 + queue_delayed_work(xprtiod_workqueue, 2407 + &transport->connect_worker, 2408 + delay); 2449 2409 } 2450 2410 2451 2411 /** ··· 2992 2960 2993 2961 xprt->ops = &xs_tcp_ops; 2994 2962 xprt->timeout = &xs_tcp_default_timeout; 2963 + 2964 + xprt->max_reconnect_timeout = xprt->timeout->to_maxval; 2995 2965 2996 2966 INIT_WORK(&transport->recv_worker, xs_tcp_data_receive_workfn); 2997 2967 INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_setup_socket);