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
6464 nlm_init->protocol, nlm_version,
6565 nlm_init->hostname, nlm_init->noresvport,
6666 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;
7171
7272 return host;
73+out_nobind:
74+ nlmclnt_release_host(host);
75+out_nohost:
76+ lockd_down(nlm_init->net);
77+ return ERR_PTR(-ENOLCK);
7378 }
7479 EXPORT_SYMBOL_GPL(nlmclnt_init);
7580
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
125125 {
126126 struct nlm_args *argp = &req->a_args;
127127 struct nlm_lock *lock = &argp->lock;
128+ char *nodename = req->a_host->h_rpcclnt->cl_nodename;
128129
129130 nlmclnt_next_cookie(&argp->cookie);
130131 memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh));
131− lock->caller = utsname()->nodename;
132+ lock->caller = nodename;
132133 lock->oh.data = req->a_owner;
133134 lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
134135 (unsigned int)fl->fl_u.nfs_fl.owner->pid,
135− utsname()->nodename);
136+ nodename);
136137 lock->svid = fl->fl_u.nfs_fl.owner->pid;
137138 lock->fl.fl_start = fl->fl_start;
138139 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
463463 unlock_new_inode(inode);
464464 } else
465465 nfs_refresh_inode(inode, fattr);
466− nfs_setsecurity(inode, fattr, label);
467466 dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n",
468467 inode->i_sb->s_id,
469468 (long long)NFS_FILEID(inode),
@@ -963,9 +962,15 @@ EXPORT_SYMBOL_GPL(nfs_revalidate_inode); · 493 unmodified lines
963962 static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
964963 {
965964 struct nfs_inode *nfsi = NFS_I(inode);
966−
965+ int ret;
966+
967967 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);
969974 if (ret < 0)
970975 return ret;
971976 }
fs/nfs/nfs4proc.c+3−5
@@ -3071,15 +3071,13 @@ struct rpc_clnt * · 3070 unmodified lines
30713071 nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name,
30723072 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
30733073 {
3074+ struct rpc_clnt *client = NFS_CLIENT(dir);
30743075 int status;
3075− struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir));
30763076
30773077 status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL);
3078− if (status < 0) {
3079− rpc_shutdown_client(client);
3078+ if (status < 0)
30803079 return ERR_PTR(status);
3081− }
3082− return client;
3080+ return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
30833081 }
30843082
30853083 static 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
24782478 if (server->flags & NFS_MOUNT_NOAC)
24792479 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
24802480
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+
24812485 /* Get a superblock - note that we may end up sharing one that already exists */
24822486 s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
24832487 if (IS_ERR(s)) {
include/linux/sunrpc/sched.h+1−0
@@ -121,6 +121,7 @@ struct rpc_task_setup { · 120 unmodified lines
121121 #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */
122122 #define RPC_TASK_SENT 0x0800 /* message was sent */
123123 #define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */
124+#define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */
124125
125126 #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
126127 #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
16601660 task->tk_action = call_connect_status;
16611661 if (task->tk_status < 0)
16621662 return;
1663+ if (task->tk_flags & RPC_TASK_NOCONNECT) {
1664+ rpc_exit(task, -ENOTCONN);
1665+ return;
1666+ }
16631667 xprt_connect(task);
16641668 }
16651669 }
net/sunrpc/netns.h+1−0
@@ -23,6 +23,7 @@ struct sunrpc_net { · 22 unmodified lines
2323 struct rpc_clnt *rpcb_local_clnt4;
2424 spinlock_t rpcb_clnt_lock;
2525 unsigned int rpcb_users;
26+ unsigned int rpcb_is_af_local : 1;
2627
2728 struct mutex gssp_lock;
2829 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
204204 }
205205
206206 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)
208209 {
209210 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
210211
211212 /* Protected by rpcb_create_local_mutex */
212213 sn->rpcb_local_clnt = clnt;
213214 sn->rpcb_local_clnt4 = clnt4;
215+ sn->rpcb_is_af_local = is_af_local ? 1 : 0;
214216 smp_wmb();
215217 sn->rpcb_users = 1;
216218 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
238240 .program = &rpcb_program,
239241 .version = RPCBVERS_2,
240242 .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,
241251 };
242252 struct rpc_clnt *clnt, *clnt4;
243253 int result = 0;
@@ -263,7 +273,7 @@ static int rpcb_create_local_unix(struct net *net) · 19 unmodified lines
263273 clnt4 = NULL;
264274 }
265275
266− rpcb_set_local(net, clnt, clnt4);
276+ rpcb_set_local(net, clnt, clnt4, true);
267277
268278 out:
269279 return result;
@@ -315,7 +325,7 @@ static int rpcb_create_local_net(struct net *net) · 45 unmodified lines
315325 clnt4 = NULL;
316326 }
317327
318− rpcb_set_local(net, clnt, clnt4);
328+ rpcb_set_local(net, clnt, clnt4, false);
319329
320330 out:
321331 return result;
@@ -376,13 +386,16 @@ static struct rpc_clnt *rpcb_create(struct net *net, const char *hostname, · 54 unmodified lines
376386 return rpc_create(&args);
377387 }
378388
379−static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg)
389+static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
380390 {
381− int result, error = 0;
391+ int flags = RPC_TASK_NOCONNECT;
392+ int error, result = 0;
382393
394+ if (is_set || !sn->rpcb_is_af_local)
395+ flags = RPC_TASK_SOFTCONN;
383396 msg->rpc_resp = &result;
384397
385− error = rpc_call_sync(clnt, msg, RPC_TASK_SOFTCONN);
398+ error = rpc_call_sync(clnt, msg, flags);
386399 if (error < 0) {
387400 dprintk("RPC: failed to contact local rpcbind "
388401 "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
439452 .rpc_argp = &map,
440453 };
441454 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
455+ bool is_set = false;
442456
443457 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
444458 "rpcbind\n", (port ? "" : "un"),
445459 prog, vers, prot, port);
446460
447461 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
448− if (port)
462+ if (port != 0) {
449463 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
464+ is_set = true;
465+ }
450466
451− return rpcb_register_call(sn->rpcb_local_clnt, &msg);
467+ return rpcb_register_call(sn, sn->rpcb_local_clnt, &msg, is_set);
452468 }
453469
454470 /*
@@ -461,6 +477,7 @@ static int rpcb_register_inet4(struct sunrpc_net *sn, · 6 unmodified lines
461477 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
462478 struct rpcbind_args *map = msg->rpc_argp;
463479 unsigned short port = ntohs(sin->sin_port);
480+ bool is_set = false;
464481 int result;
465482
466483 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
@@ -471,10 +488,12 @@ static int rpcb_register_inet4(struct sunrpc_net *sn, · 4 unmodified lines
471488 map->r_addr, map->r_netid);
472489
473490 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
474− if (port)
491+ if (port != 0) {
475492 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
493+ is_set = true;
494+ }
476495
477− result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
496+ result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
478497 kfree(map->r_addr);
479498 return result;
480499 }
@@ -489,6 +508,7 @@ static int rpcb_register_inet6(struct sunrpc_net *sn, · 8 unmodified lines
489508 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
490509 struct rpcbind_args *map = msg->rpc_argp;
491510 unsigned short port = ntohs(sin6->sin6_port);
511+ bool is_set = false;
492512 int result;
493513
494514 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
@@ -499,10 +519,12 @@ static int rpcb_register_inet6(struct sunrpc_net *sn, · 4 unmodified lines
499519 map->r_addr, map->r_netid);
500520
501521 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
502− if (port)
522+ if (port != 0) {
503523 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
524+ is_set = true;
525+ }
504526
505− result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
527+ result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
506528 kfree(map->r_addr);
507529 return result;
508530 }
@@ -519,7 +541,7 @@ static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn, · 10 unmodified lines
519541 map->r_addr = "";
520542 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
521543
522− return rpcb_register_call(sn->rpcb_local_clnt4, msg);
544+ return rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, false);
523545 }
524546
525547 /**

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