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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-3.11-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:

- Stable patch for lockd to fix Oopses due to inappropriate calls to
utsname()->nodename

- Stable patches for sunrpc to fix Oopses on shutdown when using
AF_LOCAL sockets with rpcbind

- Fix memory leak and error checking issues in nfs4_proc_lookup_mountpoint

- Fix a regression with the sync mount option failing to work for nfs4
mounts

- Fix a writeback performance issue when doing cache invalidation

- Remove an incorrect call to nfs_setsecurity in nfs_fhget

* tag 'nfs-for-3.11-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv4: Fix up nfs4_proc_lookup_mountpoint
NFS: Remove unnecessary call to nfs_setsecurity in nfs_fhget()
NFSv4: Fix the sync mount option for nfs4 mounts
NFS: Fix writeback performance issue on cache invalidation
SUNRPC: If the rpcbind channel is disconnected, fail the call to unregister
SUNRPC: Don't auto-disconnect from the local rpcbind socket
LOCKD: Don't call utsname()->nodename from nlmclnt_setlockargs

+68 -27
+9 -4
fs/lockd/clntlock.c
··· 64 64 nlm_init->protocol, nlm_version, 65 65 nlm_init->hostname, nlm_init->noresvport, 66 66 nlm_init->net); 67 - if (host == NULL) { 68 - lockd_down(nlm_init->net); 69 - return ERR_PTR(-ENOLCK); 70 - } 67 + if (host == NULL) 68 + goto out_nohost; 69 + if (host->h_rpcclnt == NULL && nlm_bind_host(host) == NULL) 70 + goto out_nobind; 71 71 72 72 return host; 73 + out_nobind: 74 + nlmclnt_release_host(host); 75 + out_nohost: 76 + lockd_down(nlm_init->net); 77 + return ERR_PTR(-ENOLCK); 73 78 } 74 79 EXPORT_SYMBOL_GPL(nlmclnt_init); 75 80
+3 -2
fs/lockd/clntproc.c
··· 125 125 { 126 126 struct nlm_args *argp = &req->a_args; 127 127 struct nlm_lock *lock = &argp->lock; 128 + char *nodename = req->a_host->h_rpcclnt->cl_nodename; 128 129 129 130 nlmclnt_next_cookie(&argp->cookie); 130 131 memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); 131 - lock->caller = utsname()->nodename; 132 + lock->caller = nodename; 132 133 lock->oh.data = req->a_owner; 133 134 lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", 134 135 (unsigned int)fl->fl_u.nfs_fl.owner->pid, 135 - utsname()->nodename); 136 + nodename); 136 137 lock->svid = fl->fl_u.nfs_fl.owner->pid; 137 138 lock->fl.fl_start = fl->fl_start; 138 139 lock->fl.fl_end = fl->fl_end;
+8 -3
fs/nfs/inode.c
··· 463 463 unlock_new_inode(inode); 464 464 } else 465 465 nfs_refresh_inode(inode, fattr); 466 - nfs_setsecurity(inode, fattr, label); 467 466 dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", 468 467 inode->i_sb->s_id, 469 468 (long long)NFS_FILEID(inode), ··· 962 963 static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) 963 964 { 964 965 struct nfs_inode *nfsi = NFS_I(inode); 965 - 966 + int ret; 967 + 966 968 if (mapping->nrpages != 0) { 967 - int ret = invalidate_inode_pages2(mapping); 969 + if (S_ISREG(inode->i_mode)) { 970 + ret = nfs_sync_mapping(mapping); 971 + if (ret < 0) 972 + return ret; 973 + } 974 + ret = invalidate_inode_pages2(mapping); 968 975 if (ret < 0) 969 976 return ret; 970 977 }
+3 -5
fs/nfs/nfs4proc.c
··· 3071 3071 nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, 3072 3072 struct nfs_fh *fhandle, struct nfs_fattr *fattr) 3073 3073 { 3074 + struct rpc_clnt *client = NFS_CLIENT(dir); 3074 3075 int status; 3075 - struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); 3076 3076 3077 3077 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL); 3078 - if (status < 0) { 3079 - rpc_shutdown_client(client); 3078 + if (status < 0) 3080 3079 return ERR_PTR(status); 3081 - } 3082 - return client; 3080 + return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client; 3083 3081 } 3084 3082 3085 3083 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
+4
fs/nfs/super.c
··· 2478 2478 if (server->flags & NFS_MOUNT_NOAC) 2479 2479 sb_mntdata.mntflags |= MS_SYNCHRONOUS; 2480 2480 2481 + if (mount_info->cloned != NULL && mount_info->cloned->sb != NULL) 2482 + if (mount_info->cloned->sb->s_flags & MS_SYNCHRONOUS) 2483 + sb_mntdata.mntflags |= MS_SYNCHRONOUS; 2484 + 2481 2485 /* Get a superblock - note that we may end up sharing one that already exists */ 2482 2486 s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); 2483 2487 if (IS_ERR(s)) {
+1
include/linux/sunrpc/sched.h
··· 121 121 #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ 122 122 #define RPC_TASK_SENT 0x0800 /* message was sent */ 123 123 #define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ 124 + #define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */ 124 125 125 126 #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) 126 127 #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
+4
net/sunrpc/clnt.c
··· 1660 1660 task->tk_action = call_connect_status; 1661 1661 if (task->tk_status < 0) 1662 1662 return; 1663 + if (task->tk_flags & RPC_TASK_NOCONNECT) { 1664 + rpc_exit(task, -ENOTCONN); 1665 + return; 1666 + } 1663 1667 xprt_connect(task); 1664 1668 } 1665 1669 }
+1
net/sunrpc/netns.h
··· 23 23 struct rpc_clnt *rpcb_local_clnt4; 24 24 spinlock_t rpcb_clnt_lock; 25 25 unsigned int rpcb_users; 26 + unsigned int rpcb_is_af_local : 1; 26 27 27 28 struct mutex gssp_lock; 28 29 wait_queue_head_t gssp_wq;
+35 -13
net/sunrpc/rpcb_clnt.c
··· 204 204 } 205 205 206 206 static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt, 207 - struct rpc_clnt *clnt4) 207 + struct rpc_clnt *clnt4, 208 + bool is_af_local) 208 209 { 209 210 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 210 211 211 212 /* Protected by rpcb_create_local_mutex */ 212 213 sn->rpcb_local_clnt = clnt; 213 214 sn->rpcb_local_clnt4 = clnt4; 215 + sn->rpcb_is_af_local = is_af_local ? 1 : 0; 214 216 smp_wmb(); 215 217 sn->rpcb_users = 1; 216 218 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: " ··· 240 238 .program = &rpcb_program, 241 239 .version = RPCBVERS_2, 242 240 .authflavor = RPC_AUTH_NULL, 241 + /* 242 + * We turn off the idle timeout to prevent the kernel 243 + * from automatically disconnecting the socket. 244 + * Otherwise, we'd have to cache the mount namespace 245 + * of the caller and somehow pass that to the socket 246 + * reconnect code. 247 + */ 248 + .flags = RPC_CLNT_CREATE_NO_IDLE_TIMEOUT, 243 249 }; 244 250 struct rpc_clnt *clnt, *clnt4; 245 251 int result = 0; ··· 273 263 clnt4 = NULL; 274 264 } 275 265 276 - rpcb_set_local(net, clnt, clnt4); 266 + rpcb_set_local(net, clnt, clnt4, true); 277 267 278 268 out: 279 269 return result; ··· 325 315 clnt4 = NULL; 326 316 } 327 317 328 - rpcb_set_local(net, clnt, clnt4); 318 + rpcb_set_local(net, clnt, clnt4, false); 329 319 330 320 out: 331 321 return result; ··· 386 376 return rpc_create(&args); 387 377 } 388 378 389 - static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg) 379 + static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set) 390 380 { 391 - int result, error = 0; 381 + int flags = RPC_TASK_NOCONNECT; 382 + int error, result = 0; 392 383 384 + if (is_set || !sn->rpcb_is_af_local) 385 + flags = RPC_TASK_SOFTCONN; 393 386 msg->rpc_resp = &result; 394 387 395 - error = rpc_call_sync(clnt, msg, RPC_TASK_SOFTCONN); 388 + error = rpc_call_sync(clnt, msg, flags); 396 389 if (error < 0) { 397 390 dprintk("RPC: failed to contact local rpcbind " 398 391 "server (errno %d).\n", -error); ··· 452 439 .rpc_argp = &map, 453 440 }; 454 441 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 442 + bool is_set = false; 455 443 456 444 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 457 445 "rpcbind\n", (port ? "" : "un"), 458 446 prog, vers, prot, port); 459 447 460 448 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET]; 461 - if (port) 449 + if (port != 0) { 462 450 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET]; 451 + is_set = true; 452 + } 463 453 464 - return rpcb_register_call(sn->rpcb_local_clnt, &msg); 454 + return rpcb_register_call(sn, sn->rpcb_local_clnt, &msg, is_set); 465 455 } 466 456 467 457 /* ··· 477 461 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; 478 462 struct rpcbind_args *map = msg->rpc_argp; 479 463 unsigned short port = ntohs(sin->sin_port); 464 + bool is_set = false; 480 465 int result; 481 466 482 467 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); ··· 488 471 map->r_addr, map->r_netid); 489 472 490 473 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; 491 - if (port) 474 + if (port != 0) { 492 475 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 476 + is_set = true; 477 + } 493 478 494 - result = rpcb_register_call(sn->rpcb_local_clnt4, msg); 479 + result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set); 495 480 kfree(map->r_addr); 496 481 return result; 497 482 } ··· 508 489 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap; 509 490 struct rpcbind_args *map = msg->rpc_argp; 510 491 unsigned short port = ntohs(sin6->sin6_port); 492 + bool is_set = false; 511 493 int result; 512 494 513 495 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); ··· 519 499 map->r_addr, map->r_netid); 520 500 521 501 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; 522 - if (port) 502 + if (port != 0) { 523 503 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 504 + is_set = true; 505 + } 524 506 525 - result = rpcb_register_call(sn->rpcb_local_clnt4, msg); 507 + result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set); 526 508 kfree(map->r_addr); 527 509 return result; 528 510 } ··· 541 519 map->r_addr = ""; 542 520 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; 543 521 544 - return rpcb_register_call(sn->rpcb_local_clnt4, msg); 522 + return rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, false); 545 523 } 546 524 547 525 /**