History

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

Linus Torvalds committed 13 years ago

Commit b8ea0d02 parents 022e5d0 b72888c9 files · +68 −27Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t