aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/Kconfig35
-rw-r--r--fs/Makefile1
-rw-r--r--fs/lockd/clntlock.c113
-rw-r--r--fs/lockd/clntproc.c40
-rw-r--r--fs/lockd/host.c8
-rw-r--r--fs/lockd/mon.c7
-rw-r--r--fs/locks.c6
-rw-r--r--fs/nfs/Makefile1
-rw-r--r--fs/nfs/callback.c1
-rw-r--r--fs/nfs/callback_proc.c1
-rw-r--r--fs/nfs/callback_xdr.c2
-rw-r--r--fs/nfs/delegation.c1
-rw-r--r--fs/nfs/dir.c160
-rw-r--r--fs/nfs/direct.c2
-rw-r--r--fs/nfs/file.c48
-rw-r--r--fs/nfs/idmap.c1
-rw-r--r--fs/nfs/inode.c427
-rw-r--r--fs/nfs/mount_clnt.c4
-rw-r--r--fs/nfs/nfs3acl.c403
-rw-r--r--fs/nfs/nfs3proc.c43
-rw-r--r--fs/nfs/nfs3xdr.c147
-rw-r--r--fs/nfs/nfs4_fs.h253
-rw-r--r--fs/nfs/nfs4proc.c429
-rw-r--r--fs/nfs/nfs4renewd.c1
-rw-r--r--fs/nfs/nfs4state.c193
-rw-r--r--fs/nfs/nfs4xdr.c241
-rw-r--r--fs/nfs/nfsroot.c9
-rw-r--r--fs/nfs/pagelist.c142
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/read.c3
-rw-r--r--fs/nfs/write.c108
-rw-r--r--fs/nfs_common/Makefile7
-rw-r--r--fs/nfs_common/nfsacl.c257
-rw-r--r--fs/nfsd/Makefile2
-rw-r--r--fs/nfsd/nfs2acl.c336
-rw-r--r--fs/nfsd/nfs3acl.c267
-rw-r--r--fs/nfsd/nfs3xdr.c13
-rw-r--r--fs/nfsd/nfs4callback.c4
-rw-r--r--fs/nfsd/nfsproc.c1
-rw-r--r--fs/nfsd/nfssvc.c28
-rw-r--r--fs/nfsd/nfsxdr.c11
-rw-r--r--fs/nfsd/vfs.c107
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/lockd/lockd.h7
-rw-r--r--include/linux/nfs4.h2
-rw-r--r--include/linux/nfs_fs.h306
-rw-r--r--include/linux/nfs_fs_i.h5
-rw-r--r--include/linux/nfs_fs_sb.h1
-rw-r--r--include/linux/nfs_mount.h1
-rw-r--r--include/linux/nfs_page.h30
-rw-r--r--include/linux/nfs_xdr.h43
-rw-r--r--include/linux/nfsacl.h58
-rw-r--r--include/linux/nfsd/nfsd.h16
-rw-r--r--include/linux/nfsd/xdr.h4
-rw-r--r--include/linux/nfsd/xdr3.h26
-rw-r--r--include/linux/sunrpc/clnt.h6
-rw-r--r--include/linux/sunrpc/sched.h1
-rw-r--r--include/linux/sunrpc/svc.h14
-rw-r--r--include/linux/sunrpc/xdr.h21
-rw-r--r--net/sunrpc/auth.c6
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c18
-rw-r--r--net/sunrpc/clnt.c205
-rw-r--r--net/sunrpc/pmap_clnt.c9
-rw-r--r--net/sunrpc/sched.c84
-rw-r--r--net/sunrpc/sunrpc_syms.c6
-rw-r--r--net/sunrpc/svc.c36
-rw-r--r--net/sunrpc/xdr.c298
-rw-r--r--net/sunrpc/xprt.c71
68 files changed, 4135 insertions, 1004 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 178e27494b74..a7c0cc3203cb 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1268,6 +1268,7 @@ config NFS_FS
1268 depends on INET 1268 depends on INET
1269 select LOCKD 1269 select LOCKD
1270 select SUNRPC 1270 select SUNRPC
1271 select NFS_ACL_SUPPORT if NFS_V3_ACL
1271 help 1272 help
1272 If you are connected to some other (usually local) Unix computer 1273 If you are connected to some other (usually local) Unix computer
1273 (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing 1274 (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing
@@ -1310,6 +1311,16 @@ config NFS_V3
1310 1311
1311 If unsure, say Y. 1312 If unsure, say Y.
1312 1313
1314config NFS_V3_ACL
1315 bool "Provide client support for the NFSv3 ACL protocol extension"
1316 depends on NFS_V3
1317 help
1318 Implement the NFSv3 ACL protocol extension for manipulating POSIX
1319 Access Control Lists. The server should also be compiled with
1320 the NFSv3 ACL protocol extension; see the CONFIG_NFSD_V3_ACL option.
1321
1322 If unsure, say N.
1323
1313config NFS_V4 1324config NFS_V4
1314 bool "Provide NFSv4 client support (EXPERIMENTAL)" 1325 bool "Provide NFSv4 client support (EXPERIMENTAL)"
1315 depends on NFS_FS && EXPERIMENTAL 1326 depends on NFS_FS && EXPERIMENTAL
@@ -1353,6 +1364,7 @@ config NFSD
1353 select LOCKD 1364 select LOCKD
1354 select SUNRPC 1365 select SUNRPC
1355 select EXPORTFS 1366 select EXPORTFS
1367 select NFS_ACL_SUPPORT if NFSD_V3_ACL || NFSD_V2_ACL
1356 help 1368 help
1357 If you want your Linux box to act as an NFS *server*, so that other 1369 If you want your Linux box to act as an NFS *server*, so that other
1358 computers on your local network which support NFS can access certain 1370 computers on your local network which support NFS can access certain
@@ -1376,6 +1388,10 @@ config NFSD
1376 To compile the NFS server support as a module, choose M here: the 1388 To compile the NFS server support as a module, choose M here: the
1377 module will be called nfsd. If unsure, say N. 1389 module will be called nfsd. If unsure, say N.
1378 1390
1391config NFSD_V2_ACL
1392 bool
1393 depends on NFSD
1394
1379config NFSD_V3 1395config NFSD_V3
1380 bool "Provide NFSv3 server support" 1396 bool "Provide NFSv3 server support"
1381 depends on NFSD 1397 depends on NFSD
@@ -1383,6 +1399,16 @@ config NFSD_V3
1383 If you would like to include the NFSv3 server as well as the NFSv2 1399 If you would like to include the NFSv3 server as well as the NFSv2
1384 server, say Y here. If unsure, say Y. 1400 server, say Y here. If unsure, say Y.
1385 1401
1402config NFSD_V3_ACL
1403 bool "Provide server support for the NFSv3 ACL protocol extension"
1404 depends on NFSD_V3
1405 select NFSD_V2_ACL
1406 help
1407 Implement the NFSv3 ACL protocol extension for manipulating POSIX
1408 Access Control Lists on exported file systems. NFS clients should
1409 be compiled with the NFSv3 ACL protocol extension; see the
1410 CONFIG_NFS_V3_ACL option. If unsure, say N.
1411
1386config NFSD_V4 1412config NFSD_V4
1387 bool "Provide NFSv4 server support (EXPERIMENTAL)" 1413 bool "Provide NFSv4 server support (EXPERIMENTAL)"
1388 depends on NFSD_V3 && EXPERIMENTAL 1414 depends on NFSD_V3 && EXPERIMENTAL
@@ -1427,6 +1453,15 @@ config LOCKD_V4
1427config EXPORTFS 1453config EXPORTFS
1428 tristate 1454 tristate
1429 1455
1456config NFS_ACL_SUPPORT
1457 tristate
1458 select FS_POSIX_ACL
1459
1460config NFS_COMMON
1461 bool
1462 depends on NFSD || NFS_FS
1463 default y
1464
1430config SUNRPC 1465config SUNRPC
1431 tristate 1466 tristate
1432 1467
diff --git a/fs/Makefile b/fs/Makefile
index 443f2bc56ccf..fc92e59e9faf 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
31 31
32obj-$(CONFIG_FS_MBCACHE) += mbcache.o 32obj-$(CONFIG_FS_MBCACHE) += mbcache.o
33obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o 33obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o
34obj-$(CONFIG_NFS_COMMON) += nfs_common/
34 35
35obj-$(CONFIG_QUOTA) += dquot.o 36obj-$(CONFIG_QUOTA) += dquot.o
36obj-$(CONFIG_QFMT_V1) += quota_v1.o 37obj-$(CONFIG_QFMT_V1) += quota_v1.o
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index ef7103b8c5bd..006bb9e14579 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -31,7 +31,7 @@ static int reclaimer(void *ptr);
31 * This is the representation of a blocked client lock. 31 * This is the representation of a blocked client lock.
32 */ 32 */
33struct nlm_wait { 33struct nlm_wait {
34 struct nlm_wait * b_next; /* linked list */ 34 struct list_head b_list; /* linked list */
35 wait_queue_head_t b_wait; /* where to wait on */ 35 wait_queue_head_t b_wait; /* where to wait on */
36 struct nlm_host * b_host; 36 struct nlm_host * b_host;
37 struct file_lock * b_lock; /* local file lock */ 37 struct file_lock * b_lock; /* local file lock */
@@ -39,27 +39,54 @@ struct nlm_wait {
39 u32 b_status; /* grant callback status */ 39 u32 b_status; /* grant callback status */
40}; 40};
41 41
42static struct nlm_wait * nlm_blocked; 42static LIST_HEAD(nlm_blocked);
43 43
44/* 44/*
45 * Block on a lock 45 * Queue up a lock for blocking so that the GRANTED request can see it
46 */ 46 */
47int 47int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl)
48nlmclnt_block(struct nlm_host *host, struct file_lock *fl, u32 *statp) 48{
49 struct nlm_wait *block;
50
51 BUG_ON(req->a_block != NULL);
52 block = kmalloc(sizeof(*block), GFP_KERNEL);
53 if (block == NULL)
54 return -ENOMEM;
55 block->b_host = host;
56 block->b_lock = fl;
57 init_waitqueue_head(&block->b_wait);
58 block->b_status = NLM_LCK_BLOCKED;
59
60 list_add(&block->b_list, &nlm_blocked);
61 req->a_block = block;
62
63 return 0;
64}
65
66void nlmclnt_finish_block(struct nlm_rqst *req)
49{ 67{
50 struct nlm_wait block, **head; 68 struct nlm_wait *block = req->a_block;
51 int err;
52 u32 pstate;
53 69
54 block.b_host = host; 70 if (block == NULL)
55 block.b_lock = fl; 71 return;
56 init_waitqueue_head(&block.b_wait); 72 req->a_block = NULL;
57 block.b_status = NLM_LCK_BLOCKED; 73 list_del(&block->b_list);
58 block.b_next = nlm_blocked; 74 kfree(block);
59 nlm_blocked = █ 75}
76
77/*
78 * Block on a lock
79 */
80long nlmclnt_block(struct nlm_rqst *req, long timeout)
81{
82 struct nlm_wait *block = req->a_block;
83 long ret;
60 84
61 /* Remember pseudo nsm state */ 85 /* A borken server might ask us to block even if we didn't
62 pstate = host->h_state; 86 * request it. Just say no!
87 */
88 if (!req->a_args.block)
89 return -EAGAIN;
63 90
64 /* Go to sleep waiting for GRANT callback. Some servers seem 91 /* Go to sleep waiting for GRANT callback. Some servers seem
65 * to lose callbacks, however, so we're going to poll from 92 * to lose callbacks, however, so we're going to poll from
@@ -69,28 +96,16 @@ nlmclnt_block(struct nlm_host *host, struct file_lock *fl, u32 *statp)
69 * a 1 minute timeout would do. See the comment before 96 * a 1 minute timeout would do. See the comment before
70 * nlmclnt_lock for an explanation. 97 * nlmclnt_lock for an explanation.
71 */ 98 */
72 sleep_on_timeout(&block.b_wait, 30*HZ); 99 ret = wait_event_interruptible_timeout(block->b_wait,
73 100 block->b_status != NLM_LCK_BLOCKED,
74 for (head = &nlm_blocked; *head; head = &(*head)->b_next) { 101 timeout);
75 if (*head == &block) {
76 *head = block.b_next;
77 break;
78 }
79 }
80 102
81 if (!signalled()) { 103 if (block->b_status != NLM_LCK_BLOCKED) {
82 *statp = block.b_status; 104 req->a_res.status = block->b_status;
83 return 0; 105 block->b_status = NLM_LCK_BLOCKED;
84 } 106 }
85 107
86 /* Okay, we were interrupted. Cancel the pending request 108 return ret;
87 * unless the server has rebooted.
88 */
89 if (pstate == host->h_state && (err = nlmclnt_cancel(host, fl)) < 0)
90 printk(KERN_NOTICE
91 "lockd: CANCEL call failed (errno %d)\n", -err);
92
93 return -ERESTARTSYS;
94} 109}
95 110
96/* 111/*
@@ -100,27 +115,23 @@ u32
100nlmclnt_grant(struct nlm_lock *lock) 115nlmclnt_grant(struct nlm_lock *lock)
101{ 116{
102 struct nlm_wait *block; 117 struct nlm_wait *block;
118 u32 res = nlm_lck_denied;
103 119
104 /* 120 /*
105 * Look up blocked request based on arguments. 121 * Look up blocked request based on arguments.
106 * Warning: must not use cookie to match it! 122 * Warning: must not use cookie to match it!
107 */ 123 */
108 for (block = nlm_blocked; block; block = block->b_next) { 124 list_for_each_entry(block, &nlm_blocked, b_list) {
109 if (nlm_compare_locks(block->b_lock, &lock->fl)) 125 if (nlm_compare_locks(block->b_lock, &lock->fl)) {
110 break; 126 /* Alright, we found a lock. Set the return status
127 * and wake up the caller
128 */
129 block->b_status = NLM_LCK_GRANTED;
130 wake_up(&block->b_wait);
131 res = nlm_granted;
132 }
111 } 133 }
112 134 return res;
113 /* Ooops, no blocked request found. */
114 if (block == NULL)
115 return nlm_lck_denied;
116
117 /* Alright, we found the lock. Set the return status and
118 * wake up the caller.
119 */
120 block->b_status = NLM_LCK_GRANTED;
121 wake_up(&block->b_wait);
122
123 return nlm_granted;
124} 135}
125 136
126/* 137/*
@@ -230,7 +241,7 @@ restart:
230 host->h_reclaiming = 0; 241 host->h_reclaiming = 0;
231 242
232 /* Now, wake up all processes that sleep on a blocked lock */ 243 /* Now, wake up all processes that sleep on a blocked lock */
233 for (block = nlm_blocked; block; block = block->b_next) { 244 list_for_each_entry(block, &nlm_blocked, b_list) {
234 if (block->b_host == host) { 245 if (block->b_host == host) {
235 block->b_status = NLM_LCK_DENIED_GRACE_PERIOD; 246 block->b_status = NLM_LCK_DENIED_GRACE_PERIOD;
236 wake_up(&block->b_wait); 247 wake_up(&block->b_wait);
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a4407619b1f1..fd77ed1d710d 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -21,6 +21,7 @@
21 21
22#define NLMDBG_FACILITY NLMDBG_CLIENT 22#define NLMDBG_FACILITY NLMDBG_CLIENT
23#define NLMCLNT_GRACE_WAIT (5*HZ) 23#define NLMCLNT_GRACE_WAIT (5*HZ)
24#define NLMCLNT_POLL_TIMEOUT (30*HZ)
24 25
25static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); 26static int nlmclnt_test(struct nlm_rqst *, struct file_lock *);
26static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); 27static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
@@ -553,7 +554,8 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
553{ 554{
554 struct nlm_host *host = req->a_host; 555 struct nlm_host *host = req->a_host;
555 struct nlm_res *resp = &req->a_res; 556 struct nlm_res *resp = &req->a_res;
556 int status; 557 long timeout;
558 int status;
557 559
558 if (!host->h_monitored && nsm_monitor(host) < 0) { 560 if (!host->h_monitored && nsm_monitor(host) < 0) {
559 printk(KERN_NOTICE "lockd: failed to monitor %s\n", 561 printk(KERN_NOTICE "lockd: failed to monitor %s\n",
@@ -562,15 +564,32 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
562 goto out; 564 goto out;
563 } 565 }
564 566
565 do { 567 if (req->a_args.block) {
566 if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0) { 568 status = nlmclnt_prepare_block(req, host, fl);
567 if (resp->status != NLM_LCK_BLOCKED)
568 break;
569 status = nlmclnt_block(host, fl, &resp->status);
570 }
571 if (status < 0) 569 if (status < 0)
572 goto out; 570 goto out;
573 } while (resp->status == NLM_LCK_BLOCKED && req->a_args.block); 571 }
572 for(;;) {
573 status = nlmclnt_call(req, NLMPROC_LOCK);
574 if (status < 0)
575 goto out_unblock;
576 if (resp->status != NLM_LCK_BLOCKED)
577 break;
578 /* Wait on an NLM blocking lock */
579 timeout = nlmclnt_block(req, NLMCLNT_POLL_TIMEOUT);
580 /* Did a reclaimer thread notify us of a server reboot? */
581 if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD)
582 continue;
583 if (resp->status != NLM_LCK_BLOCKED)
584 break;
585 if (timeout >= 0)
586 continue;
587 /* We were interrupted. Send a CANCEL request to the server
588 * and exit
589 */
590 status = (int)timeout;
591 goto out_unblock;
592 }
574 593
575 if (resp->status == NLM_LCK_GRANTED) { 594 if (resp->status == NLM_LCK_GRANTED) {
576 fl->fl_u.nfs_fl.state = host->h_state; 595 fl->fl_u.nfs_fl.state = host->h_state;
@@ -579,6 +598,11 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
579 do_vfs_lock(fl); 598 do_vfs_lock(fl);
580 } 599 }
581 status = nlm_stat_to_errno(resp->status); 600 status = nlm_stat_to_errno(resp->status);
601out_unblock:
602 nlmclnt_finish_block(req);
603 /* Cancel the blocked request if it is still pending */
604 if (resp->status == NLM_LCK_BLOCKED)
605 nlmclnt_cancel(host, fl);
582out: 606out:
583 nlmclnt_release_lockargs(req); 607 nlmclnt_release_lockargs(req);
584 return status; 608 return status;
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 52707c5ad6ea..82c77df81c5f 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -189,17 +189,15 @@ nlm_bind_host(struct nlm_host *host)
189 goto forgetit; 189 goto forgetit;
190 190
191 xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout); 191 xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
192 xprt->nocong = 1; /* No congestion control for NLM */
193 xprt->resvport = 1; /* NLM requires a reserved port */
192 194
193 /* Existing NLM servers accept AUTH_UNIX only */ 195 /* Existing NLM servers accept AUTH_UNIX only */
194 clnt = rpc_create_client(xprt, host->h_name, &nlm_program, 196 clnt = rpc_create_client(xprt, host->h_name, &nlm_program,
195 host->h_version, RPC_AUTH_UNIX); 197 host->h_version, RPC_AUTH_UNIX);
196 if (IS_ERR(clnt)) { 198 if (IS_ERR(clnt))
197 xprt_destroy(xprt);
198 goto forgetit; 199 goto forgetit;
199 }
200 clnt->cl_autobind = 1; /* turn on pmap queries */ 200 clnt->cl_autobind = 1; /* turn on pmap queries */
201 xprt->nocong = 1; /* No congestion control for NLM */
202 xprt->resvport = 1; /* NLM requires a reserved port */
203 201
204 host->h_rpcclnt = clnt; 202 host->h_rpcclnt = clnt;
205 } 203 }
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 6fc1bebeec1d..2d144abe84ad 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -115,20 +115,19 @@ nsm_create(void)
115 xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL); 115 xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL);
116 if (IS_ERR(xprt)) 116 if (IS_ERR(xprt))
117 return (struct rpc_clnt *)xprt; 117 return (struct rpc_clnt *)xprt;
118 xprt->resvport = 1; /* NSM requires a reserved port */
118 119
119 clnt = rpc_create_client(xprt, "localhost", 120 clnt = rpc_create_client(xprt, "localhost",
120 &nsm_program, SM_VERSION, 121 &nsm_program, SM_VERSION,
121 RPC_AUTH_NULL); 122 RPC_AUTH_NULL);
122 if (IS_ERR(clnt)) 123 if (IS_ERR(clnt))
123 goto out_destroy; 124 goto out_err;
124 clnt->cl_softrtry = 1; 125 clnt->cl_softrtry = 1;
125 clnt->cl_chatty = 1; 126 clnt->cl_chatty = 1;
126 clnt->cl_oneshot = 1; 127 clnt->cl_oneshot = 1;
127 xprt->resvport = 1; /* NSM requires a reserved port */
128 return clnt; 128 return clnt;
129 129
130out_destroy: 130out_err:
131 xprt_destroy(xprt);
132 return clnt; 131 return clnt;
133} 132}
134 133
diff --git a/fs/locks.c b/fs/locks.c
index 3fa6a7ce57a7..a0bc03495bd4 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1548,6 +1548,8 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
1548 1548
1549 if (filp->f_op && filp->f_op->lock) { 1549 if (filp->f_op && filp->f_op->lock) {
1550 error = filp->f_op->lock(filp, F_GETLK, &file_lock); 1550 error = filp->f_op->lock(filp, F_GETLK, &file_lock);
1551 if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
1552 file_lock.fl_ops->fl_release_private(&file_lock);
1551 if (error < 0) 1553 if (error < 0)
1552 goto out; 1554 goto out;
1553 else 1555 else
@@ -1690,6 +1692,8 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
1690 1692
1691 if (filp->f_op && filp->f_op->lock) { 1693 if (filp->f_op && filp->f_op->lock) {
1692 error = filp->f_op->lock(filp, F_GETLK, &file_lock); 1694 error = filp->f_op->lock(filp, F_GETLK, &file_lock);
1695 if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
1696 file_lock.fl_ops->fl_release_private(&file_lock);
1693 if (error < 0) 1697 if (error < 0)
1694 goto out; 1698 goto out;
1695 else 1699 else
@@ -1873,6 +1877,8 @@ void locks_remove_flock(struct file *filp)
1873 .fl_end = OFFSET_MAX, 1877 .fl_end = OFFSET_MAX,
1874 }; 1878 };
1875 filp->f_op->flock(filp, F_SETLKW, &fl); 1879 filp->f_op->flock(filp, F_SETLKW, &fl);
1880 if (fl.fl_ops && fl.fl_ops->fl_release_private)
1881 fl.fl_ops->fl_release_private(&fl);
1876 } 1882 }
1877 1883
1878 lock_kernel(); 1884 lock_kernel();
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index b4baa031edf4..8b3bb715d177 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -8,6 +8,7 @@ nfs-y := dir.o file.o inode.o nfs2xdr.o pagelist.o \
8 proc.o read.o symlink.o unlink.o write.o 8 proc.o read.o symlink.o unlink.o write.o
9nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o 9nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
10nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o 10nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
11nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
11nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ 12nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
12 delegation.o idmap.o \ 13 delegation.o idmap.o \
13 callback.o callback_xdr.o callback_proc.o 14 callback.o callback_xdr.o callback_proc.o
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 560d6175dd58..f2ca782aba33 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -14,6 +14,7 @@
14#include <linux/sunrpc/svc.h> 14#include <linux/sunrpc/svc.h>
15#include <linux/sunrpc/svcsock.h> 15#include <linux/sunrpc/svcsock.h>
16#include <linux/nfs_fs.h> 16#include <linux/nfs_fs.h>
17#include "nfs4_fs.h"
17#include "callback.h" 18#include "callback.h"
18 19
19#define NFSDBG_FACILITY NFSDBG_CALLBACK 20#define NFSDBG_FACILITY NFSDBG_CALLBACK
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index ece27e42b93b..65f1e19e4d19 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -8,6 +8,7 @@
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/nfs4.h> 9#include <linux/nfs4.h>
10#include <linux/nfs_fs.h> 10#include <linux/nfs_fs.h>
11#include "nfs4_fs.h"
11#include "callback.h" 12#include "callback.h"
12#include "delegation.h" 13#include "delegation.h"
13 14
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index d271df9df2b2..7c33b9a81a94 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -10,6 +10,7 @@
10#include <linux/sunrpc/svc.h> 10#include <linux/sunrpc/svc.h>
11#include <linux/nfs4.h> 11#include <linux/nfs4.h>
12#include <linux/nfs_fs.h> 12#include <linux/nfs_fs.h>
13#include "nfs4_fs.h"
13#include "callback.h" 14#include "callback.h"
14 15
15#define CB_OP_TAGLEN_MAXSZ (512) 16#define CB_OP_TAGLEN_MAXSZ (512)
@@ -410,7 +411,6 @@ static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp
410 xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base); 411 xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
411 412
412 p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); 413 p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
413 rqstp->rq_res.head[0].iov_len = PAGE_SIZE;
414 xdr_init_encode(&xdr_out, &rqstp->rq_res, p); 414 xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
415 415
416 decode_compound_hdr_arg(&xdr_in, &hdr_arg); 416 decode_compound_hdr_arg(&xdr_in, &hdr_arg);
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 5b9c60f97791..d7f7eb669d03 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -16,6 +16,7 @@
16#include <linux/nfs_fs.h> 16#include <linux/nfs_fs.h>
17#include <linux/nfs_xdr.h> 17#include <linux/nfs_xdr.h>
18 18
19#include "nfs4_fs.h"
19#include "delegation.h" 20#include "delegation.h"
20 21
21static struct nfs_delegation *nfs_alloc_delegation(void) 22static struct nfs_delegation *nfs_alloc_delegation(void)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index ff6155f5e8d9..b38a57e78a63 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -32,6 +32,7 @@
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/namei.h> 33#include <linux/namei.h>
34 34
35#include "nfs4_fs.h"
35#include "delegation.h" 36#include "delegation.h"
36 37
37#define NFS_PARANOIA 1 38#define NFS_PARANOIA 1
@@ -50,8 +51,10 @@ static int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
50static int nfs_rename(struct inode *, struct dentry *, 51static int nfs_rename(struct inode *, struct dentry *,
51 struct inode *, struct dentry *); 52 struct inode *, struct dentry *);
52static int nfs_fsync_dir(struct file *, struct dentry *, int); 53static int nfs_fsync_dir(struct file *, struct dentry *, int);
54static loff_t nfs_llseek_dir(struct file *, loff_t, int);
53 55
54struct file_operations nfs_dir_operations = { 56struct file_operations nfs_dir_operations = {
57 .llseek = nfs_llseek_dir,
55 .read = generic_read_dir, 58 .read = generic_read_dir,
56 .readdir = nfs_readdir, 59 .readdir = nfs_readdir,
57 .open = nfs_opendir, 60 .open = nfs_opendir,
@@ -74,6 +77,27 @@ struct inode_operations nfs_dir_inode_operations = {
74 .setattr = nfs_setattr, 77 .setattr = nfs_setattr,
75}; 78};
76 79
80#ifdef CONFIG_NFS_V3
81struct inode_operations nfs3_dir_inode_operations = {
82 .create = nfs_create,
83 .lookup = nfs_lookup,
84 .link = nfs_link,
85 .unlink = nfs_unlink,
86 .symlink = nfs_symlink,
87 .mkdir = nfs_mkdir,
88 .rmdir = nfs_rmdir,
89 .mknod = nfs_mknod,
90 .rename = nfs_rename,
91 .permission = nfs_permission,
92 .getattr = nfs_getattr,
93 .setattr = nfs_setattr,
94 .listxattr = nfs3_listxattr,
95 .getxattr = nfs3_getxattr,
96 .setxattr = nfs3_setxattr,
97 .removexattr = nfs3_removexattr,
98};
99#endif /* CONFIG_NFS_V3 */
100
77#ifdef CONFIG_NFS_V4 101#ifdef CONFIG_NFS_V4
78 102
79static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *); 103static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
@@ -90,6 +114,9 @@ struct inode_operations nfs4_dir_inode_operations = {
90 .permission = nfs_permission, 114 .permission = nfs_permission,
91 .getattr = nfs_getattr, 115 .getattr = nfs_getattr,
92 .setattr = nfs_setattr, 116 .setattr = nfs_setattr,
117 .getxattr = nfs4_getxattr,
118 .setxattr = nfs4_setxattr,
119 .listxattr = nfs4_listxattr,
93}; 120};
94 121
95#endif /* CONFIG_NFS_V4 */ 122#endif /* CONFIG_NFS_V4 */
@@ -116,7 +143,8 @@ typedef struct {
116 struct page *page; 143 struct page *page;
117 unsigned long page_index; 144 unsigned long page_index;
118 u32 *ptr; 145 u32 *ptr;
119 u64 target; 146 u64 *dir_cookie;
147 loff_t current_index;
120 struct nfs_entry *entry; 148 struct nfs_entry *entry;
121 decode_dirent_t decode; 149 decode_dirent_t decode;
122 int plus; 150 int plus;
@@ -164,12 +192,10 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
164 NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; 192 NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME;
165 /* Ensure consistent page alignment of the data. 193 /* Ensure consistent page alignment of the data.
166 * Note: assumes we have exclusive access to this mapping either 194 * Note: assumes we have exclusive access to this mapping either
167 * throught inode->i_sem or some other mechanism. 195 * through inode->i_sem or some other mechanism.
168 */ 196 */
169 if (page->index == 0) { 197 if (page->index == 0)
170 invalidate_inode_pages(inode->i_mapping); 198 invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);
171 NFS_I(inode)->readdir_timestamp = timestamp;
172 }
173 unlock_page(page); 199 unlock_page(page);
174 return 0; 200 return 0;
175 error: 201 error:
@@ -202,22 +228,22 @@ void dir_page_release(nfs_readdir_descriptor_t *desc)
202 228
203/* 229/*
204 * Given a pointer to a buffer that has already been filled by a call 230 * Given a pointer to a buffer that has already been filled by a call
205 * to readdir, find the next entry. 231 * to readdir, find the next entry with cookie '*desc->dir_cookie'.
206 * 232 *
207 * If the end of the buffer has been reached, return -EAGAIN, if not, 233 * If the end of the buffer has been reached, return -EAGAIN, if not,
208 * return the offset within the buffer of the next entry to be 234 * return the offset within the buffer of the next entry to be
209 * read. 235 * read.
210 */ 236 */
211static inline 237static inline
212int find_dirent(nfs_readdir_descriptor_t *desc, struct page *page) 238int find_dirent(nfs_readdir_descriptor_t *desc)
213{ 239{
214 struct nfs_entry *entry = desc->entry; 240 struct nfs_entry *entry = desc->entry;
215 int loop_count = 0, 241 int loop_count = 0,
216 status; 242 status;
217 243
218 while((status = dir_decode(desc)) == 0) { 244 while((status = dir_decode(desc)) == 0) {
219 dfprintk(VFS, "NFS: found cookie %Lu\n", (long long)entry->cookie); 245 dfprintk(VFS, "NFS: found cookie %Lu\n", (unsigned long long)entry->cookie);
220 if (entry->prev_cookie == desc->target) 246 if (entry->prev_cookie == *desc->dir_cookie)
221 break; 247 break;
222 if (loop_count++ > 200) { 248 if (loop_count++ > 200) {
223 loop_count = 0; 249 loop_count = 0;
@@ -229,8 +255,44 @@ int find_dirent(nfs_readdir_descriptor_t *desc, struct page *page)
229} 255}
230 256
231/* 257/*
232 * Find the given page, and call find_dirent() in order to try to 258 * Given a pointer to a buffer that has already been filled by a call
233 * return the next entry. 259 * to readdir, find the entry at offset 'desc->file->f_pos'.
260 *
261 * If the end of the buffer has been reached, return -EAGAIN, if not,
262 * return the offset within the buffer of the next entry to be
263 * read.
264 */
265static inline
266int find_dirent_index(nfs_readdir_descriptor_t *desc)
267{
268 struct nfs_entry *entry = desc->entry;
269 int loop_count = 0,
270 status;
271
272 for(;;) {
273 status = dir_decode(desc);
274 if (status)
275 break;
276
277 dfprintk(VFS, "NFS: found cookie %Lu at index %Ld\n", (unsigned long long)entry->cookie, desc->current_index);
278
279 if (desc->file->f_pos == desc->current_index) {
280 *desc->dir_cookie = entry->cookie;
281 break;
282 }
283 desc->current_index++;
284 if (loop_count++ > 200) {
285 loop_count = 0;
286 schedule();
287 }
288 }
289 dfprintk(VFS, "NFS: find_dirent_index() returns %d\n", status);
290 return status;
291}
292
293/*
294 * Find the given page, and call find_dirent() or find_dirent_index in
295 * order to try to return the next entry.
234 */ 296 */
235static inline 297static inline
236int find_dirent_page(nfs_readdir_descriptor_t *desc) 298int find_dirent_page(nfs_readdir_descriptor_t *desc)
@@ -253,7 +315,10 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
253 /* NOTE: Someone else may have changed the READDIRPLUS flag */ 315 /* NOTE: Someone else may have changed the READDIRPLUS flag */
254 desc->page = page; 316 desc->page = page;
255 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ 317 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
256 status = find_dirent(desc, page); 318 if (*desc->dir_cookie != 0)
319 status = find_dirent(desc);
320 else
321 status = find_dirent_index(desc);
257 if (status < 0) 322 if (status < 0)
258 dir_page_release(desc); 323 dir_page_release(desc);
259 out: 324 out:
@@ -268,7 +333,8 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
268 * Recurse through the page cache pages, and return a 333 * Recurse through the page cache pages, and return a
269 * filled nfs_entry structure of the next directory entry if possible. 334 * filled nfs_entry structure of the next directory entry if possible.
270 * 335 *
271 * The target for the search is 'desc->target'. 336 * The target for the search is '*desc->dir_cookie' if non-0,
337 * 'desc->file->f_pos' otherwise
272 */ 338 */
273static inline 339static inline
274int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) 340int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
@@ -276,7 +342,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
276 int loop_count = 0; 342 int loop_count = 0;
277 int res; 343 int res;
278 344
279 dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (long long)desc->target); 345 /* Always search-by-index from the beginning of the cache */
346 if (*desc->dir_cookie == 0) {
347 dfprintk(VFS, "NFS: readdir_search_pagecache() searching for offset %Ld\n", (long long)desc->file->f_pos);
348 desc->page_index = 0;
349 desc->entry->cookie = desc->entry->prev_cookie = 0;
350 desc->entry->eof = 0;
351 desc->current_index = 0;
352 } else
353 dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
354
280 for (;;) { 355 for (;;) {
281 res = find_dirent_page(desc); 356 res = find_dirent_page(desc);
282 if (res != -EAGAIN) 357 if (res != -EAGAIN)
@@ -313,7 +388,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
313 int loop_count = 0, 388 int loop_count = 0,
314 res; 389 res;
315 390
316 dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)desc->target); 391 dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)entry->cookie);
317 392
318 for(;;) { 393 for(;;) {
319 unsigned d_type = DT_UNKNOWN; 394 unsigned d_type = DT_UNKNOWN;
@@ -333,10 +408,11 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
333 } 408 }
334 409
335 res = filldir(dirent, entry->name, entry->len, 410 res = filldir(dirent, entry->name, entry->len,
336 entry->prev_cookie, fileid, d_type); 411 file->f_pos, fileid, d_type);
337 if (res < 0) 412 if (res < 0)
338 break; 413 break;
339 file->f_pos = desc->target = entry->cookie; 414 file->f_pos++;
415 *desc->dir_cookie = entry->cookie;
340 if (dir_decode(desc) != 0) { 416 if (dir_decode(desc) != 0) {
341 desc->page_index ++; 417 desc->page_index ++;
342 break; 418 break;
@@ -349,7 +425,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
349 dir_page_release(desc); 425 dir_page_release(desc);
350 if (dentry != NULL) 426 if (dentry != NULL)
351 dput(dentry); 427 dput(dentry);
352 dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (long long)desc->target, res); 428 dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (unsigned long long)*desc->dir_cookie, res);
353 return res; 429 return res;
354} 430}
355 431
@@ -375,14 +451,14 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
375 struct page *page = NULL; 451 struct page *page = NULL;
376 int status; 452 int status;
377 453
378 dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (long long)desc->target); 454 dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
379 455
380 page = alloc_page(GFP_HIGHUSER); 456 page = alloc_page(GFP_HIGHUSER);
381 if (!page) { 457 if (!page) {
382 status = -ENOMEM; 458 status = -ENOMEM;
383 goto out; 459 goto out;
384 } 460 }
385 desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->target, 461 desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, *desc->dir_cookie,
386 page, 462 page,
387 NFS_SERVER(inode)->dtsize, 463 NFS_SERVER(inode)->dtsize,
388 desc->plus); 464 desc->plus);
@@ -391,7 +467,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
391 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ 467 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
392 if (desc->error >= 0) { 468 if (desc->error >= 0) {
393 if ((status = dir_decode(desc)) == 0) 469 if ((status = dir_decode(desc)) == 0)
394 desc->entry->prev_cookie = desc->target; 470 desc->entry->prev_cookie = *desc->dir_cookie;
395 } else 471 } else
396 status = -EIO; 472 status = -EIO;
397 if (status < 0) 473 if (status < 0)
@@ -412,8 +488,9 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
412 goto out; 488 goto out;
413} 489}
414 490
415/* The file offset position is now represented as a true offset into the 491/* The file offset position represents the dirent entry number. A
416 * page cache as is the case in most of the other filesystems. 492 last cookie cache takes care of the common case of reading the
493 whole directory.
417 */ 494 */
418static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 495static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
419{ 496{
@@ -435,15 +512,15 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
435 } 512 }
436 513
437 /* 514 /*
438 * filp->f_pos points to the file offset in the page cache. 515 * filp->f_pos points to the dirent entry number.
439 * but if the cache has meanwhile been zapped, we need to 516 * *desc->dir_cookie has the cookie for the next entry. We have
440 * read from the last dirent to revalidate f_pos 517 * to either find the entry with the appropriate number or
441 * itself. 518 * revalidate the cookie.
442 */ 519 */
443 memset(desc, 0, sizeof(*desc)); 520 memset(desc, 0, sizeof(*desc));
444 521
445 desc->file = filp; 522 desc->file = filp;
446 desc->target = filp->f_pos; 523 desc->dir_cookie = &((struct nfs_open_context *)filp->private_data)->dir_cookie;
447 desc->decode = NFS_PROTO(inode)->decode_dirent; 524 desc->decode = NFS_PROTO(inode)->decode_dirent;
448 desc->plus = NFS_USE_READDIRPLUS(inode); 525 desc->plus = NFS_USE_READDIRPLUS(inode);
449 526
@@ -455,9 +532,10 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
455 532
456 while(!desc->entry->eof) { 533 while(!desc->entry->eof) {
457 res = readdir_search_pagecache(desc); 534 res = readdir_search_pagecache(desc);
535
458 if (res == -EBADCOOKIE) { 536 if (res == -EBADCOOKIE) {
459 /* This means either end of directory */ 537 /* This means either end of directory */
460 if (desc->entry->cookie != desc->target) { 538 if (*desc->dir_cookie && desc->entry->cookie != *desc->dir_cookie) {
461 /* Or that the server has 'lost' a cookie */ 539 /* Or that the server has 'lost' a cookie */
462 res = uncached_readdir(desc, dirent, filldir); 540 res = uncached_readdir(desc, dirent, filldir);
463 if (res >= 0) 541 if (res >= 0)
@@ -490,6 +568,28 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
490 return 0; 568 return 0;
491} 569}
492 570
571loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
572{
573 down(&filp->f_dentry->d_inode->i_sem);
574 switch (origin) {
575 case 1:
576 offset += filp->f_pos;
577 case 0:
578 if (offset >= 0)
579 break;
580 default:
581 offset = -EINVAL;
582 goto out;
583 }
584 if (offset != filp->f_pos) {
585 filp->f_pos = offset;
586 ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0;
587 }
588out:
589 up(&filp->f_dentry->d_inode->i_sem);
590 return offset;
591}
592
493/* 593/*
494 * All directory operations under NFS are synchronous, so fsync() 594 * All directory operations under NFS are synchronous, so fsync()
495 * is a dummy operation. 595 * is a dummy operation.
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 68df803f27ca..d6a30c844de3 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -517,7 +517,7 @@ retry:
517 result = tot_bytes; 517 result = tot_bytes;
518 518
519out: 519out:
520 nfs_end_data_update_defer(inode); 520 nfs_end_data_update(inode);
521 nfs_writedata_free(wdata); 521 nfs_writedata_free(wdata);
522 return result; 522 return result;
523 523
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 55c907592490..5621ba9885f4 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -71,6 +71,18 @@ struct inode_operations nfs_file_inode_operations = {
71 .setattr = nfs_setattr, 71 .setattr = nfs_setattr,
72}; 72};
73 73
74#ifdef CONFIG_NFS_V3
75struct inode_operations nfs3_file_inode_operations = {
76 .permission = nfs_permission,
77 .getattr = nfs_getattr,
78 .setattr = nfs_setattr,
79 .listxattr = nfs3_listxattr,
80 .getxattr = nfs3_getxattr,
81 .setxattr = nfs3_setxattr,
82 .removexattr = nfs3_removexattr,
83};
84#endif /* CONFIG_NFS_v3 */
85
74/* Hack for future NFS swap support */ 86/* Hack for future NFS swap support */
75#ifndef IS_SWAPFILE 87#ifndef IS_SWAPFILE
76# define IS_SWAPFILE(inode) (0) 88# define IS_SWAPFILE(inode) (0)
@@ -116,6 +128,21 @@ nfs_file_release(struct inode *inode, struct file *filp)
116} 128}
117 129
118/** 130/**
131 * nfs_revalidate_file - Revalidate the page cache & related metadata
132 * @inode - pointer to inode struct
133 * @file - pointer to file
134 */
135static int nfs_revalidate_file(struct inode *inode, struct file *filp)
136{
137 int retval = 0;
138
139 if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode))
140 retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
141 nfs_revalidate_mapping(inode, filp->f_mapping);
142 return 0;
143}
144
145/**
119 * nfs_revalidate_size - Revalidate the file size 146 * nfs_revalidate_size - Revalidate the file size
120 * @inode - pointer to inode struct 147 * @inode - pointer to inode struct
121 * @file - pointer to struct file 148 * @file - pointer to struct file
@@ -137,7 +164,8 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
137 goto force_reval; 164 goto force_reval;
138 if (nfsi->npages != 0) 165 if (nfsi->npages != 0)
139 return 0; 166 return 0;
140 return nfs_revalidate_inode(server, inode); 167 if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
168 return 0;
141force_reval: 169force_reval:
142 return __nfs_revalidate_inode(server, inode); 170 return __nfs_revalidate_inode(server, inode);
143} 171}
@@ -198,7 +226,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
198 dentry->d_parent->d_name.name, dentry->d_name.name, 226 dentry->d_parent->d_name.name, dentry->d_name.name,
199 (unsigned long) count, (unsigned long) pos); 227 (unsigned long) count, (unsigned long) pos);
200 228
201 result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 229 result = nfs_revalidate_file(inode, iocb->ki_filp);
202 if (!result) 230 if (!result)
203 result = generic_file_aio_read(iocb, buf, count, pos); 231 result = generic_file_aio_read(iocb, buf, count, pos);
204 return result; 232 return result;
@@ -216,7 +244,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count,
216 dentry->d_parent->d_name.name, dentry->d_name.name, 244 dentry->d_parent->d_name.name, dentry->d_name.name,
217 (unsigned long) count, (unsigned long long) *ppos); 245 (unsigned long) count, (unsigned long long) *ppos);
218 246
219 res = nfs_revalidate_inode(NFS_SERVER(inode), inode); 247 res = nfs_revalidate_file(inode, filp);
220 if (!res) 248 if (!res)
221 res = generic_file_sendfile(filp, ppos, count, actor, target); 249 res = generic_file_sendfile(filp, ppos, count, actor, target);
222 return res; 250 return res;
@@ -232,7 +260,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
232 dfprintk(VFS, "nfs: mmap(%s/%s)\n", 260 dfprintk(VFS, "nfs: mmap(%s/%s)\n",
233 dentry->d_parent->d_name.name, dentry->d_name.name); 261 dentry->d_parent->d_name.name, dentry->d_name.name);
234 262
235 status = nfs_revalidate_inode(NFS_SERVER(inode), inode); 263 status = nfs_revalidate_file(inode, file);
236 if (!status) 264 if (!status)
237 status = generic_file_mmap(file, vma); 265 status = generic_file_mmap(file, vma);
238 return status; 266 return status;
@@ -321,9 +349,15 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
321 result = -EBUSY; 349 result = -EBUSY;
322 if (IS_SWAPFILE(inode)) 350 if (IS_SWAPFILE(inode))
323 goto out_swapfile; 351 goto out_swapfile;
324 result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 352 /*
325 if (result) 353 * O_APPEND implies that we must revalidate the file length.
326 goto out; 354 */
355 if (iocb->ki_filp->f_flags & O_APPEND) {
356 result = nfs_revalidate_file_size(inode, iocb->ki_filp);
357 if (result)
358 goto out;
359 }
360 nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
327 361
328 result = count; 362 result = count;
329 if (!count) 363 if (!count)
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 87f4f9aeac86..ffb8df91dc34 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -50,6 +50,7 @@
50#include <linux/nfs_fs.h> 50#include <linux/nfs_fs.h>
51 51
52#include <linux/nfs_idmap.h> 52#include <linux/nfs_idmap.h>
53#include "nfs4_fs.h"
53 54
54#define IDMAP_HASH_SZ 128 55#define IDMAP_HASH_SZ 128
55 56
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f2317f3e29f9..4845911f1c63 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -39,6 +39,7 @@
39#include <asm/system.h> 39#include <asm/system.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42#include "nfs4_fs.h"
42#include "delegation.h" 43#include "delegation.h"
43 44
44#define NFSDBG_FACILITY NFSDBG_VFS 45#define NFSDBG_FACILITY NFSDBG_VFS
@@ -63,6 +64,7 @@ static void nfs_clear_inode(struct inode *);
63static void nfs_umount_begin(struct super_block *); 64static void nfs_umount_begin(struct super_block *);
64static int nfs_statfs(struct super_block *, struct kstatfs *); 65static int nfs_statfs(struct super_block *, struct kstatfs *);
65static int nfs_show_options(struct seq_file *, struct vfsmount *); 66static int nfs_show_options(struct seq_file *, struct vfsmount *);
67static void nfs_zap_acl_cache(struct inode *);
66 68
67static struct rpc_program nfs_program; 69static struct rpc_program nfs_program;
68 70
@@ -106,6 +108,21 @@ static struct rpc_program nfs_program = {
106 .pipe_dir_name = "/nfs", 108 .pipe_dir_name = "/nfs",
107}; 109};
108 110
111#ifdef CONFIG_NFS_V3_ACL
112static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
113static struct rpc_version * nfsacl_version[] = {
114 [3] = &nfsacl_version3,
115};
116
117struct rpc_program nfsacl_program = {
118 .name = "nfsacl",
119 .number = NFS_ACL_PROGRAM,
120 .nrvers = sizeof(nfsacl_version) / sizeof(nfsacl_version[0]),
121 .version = nfsacl_version,
122 .stats = &nfsacl_rpcstat,
123};
124#endif /* CONFIG_NFS_V3_ACL */
125
109static inline unsigned long 126static inline unsigned long
110nfs_fattr_to_ino_t(struct nfs_fattr *fattr) 127nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
111{ 128{
@@ -118,7 +135,7 @@ nfs_write_inode(struct inode *inode, int sync)
118 int flags = sync ? FLUSH_WAIT : 0; 135 int flags = sync ? FLUSH_WAIT : 0;
119 int ret; 136 int ret;
120 137
121 ret = nfs_commit_inode(inode, 0, 0, flags); 138 ret = nfs_commit_inode(inode, flags);
122 if (ret < 0) 139 if (ret < 0)
123 return ret; 140 return ret;
124 return 0; 141 return 0;
@@ -140,10 +157,6 @@ nfs_delete_inode(struct inode * inode)
140 clear_inode(inode); 157 clear_inode(inode);
141} 158}
142 159
143/*
144 * For the moment, the only task for the NFS clear_inode method is to
145 * release the mmap credential
146 */
147static void 160static void
148nfs_clear_inode(struct inode *inode) 161nfs_clear_inode(struct inode *inode)
149{ 162{
@@ -152,6 +165,7 @@ nfs_clear_inode(struct inode *inode)
152 165
153 nfs_wb_all(inode); 166 nfs_wb_all(inode);
154 BUG_ON (!list_empty(&nfsi->open_files)); 167 BUG_ON (!list_empty(&nfsi->open_files));
168 nfs_zap_acl_cache(inode);
155 cred = nfsi->cache_access.cred; 169 cred = nfsi->cache_access.cred;
156 if (cred) 170 if (cred)
157 put_rpccred(cred); 171 put_rpccred(cred);
@@ -161,11 +175,13 @@ nfs_clear_inode(struct inode *inode)
161void 175void
162nfs_umount_begin(struct super_block *sb) 176nfs_umount_begin(struct super_block *sb)
163{ 177{
164 struct nfs_server *server = NFS_SB(sb); 178 struct rpc_clnt *rpc = NFS_SB(sb)->client;
165 struct rpc_clnt *rpc;
166 179
167 /* -EIO all pending I/O */ 180 /* -EIO all pending I/O */
168 if ((rpc = server->client) != NULL) 181 if (!IS_ERR(rpc))
182 rpc_killall_tasks(rpc);
183 rpc = NFS_SB(sb)->client_acl;
184 if (!IS_ERR(rpc))
169 rpc_killall_tasks(rpc); 185 rpc_killall_tasks(rpc);
170} 186}
171 187
@@ -366,13 +382,15 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
366 xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP, 382 xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
367 &server->addr, &timeparms); 383 &server->addr, &timeparms);
368 if (IS_ERR(xprt)) { 384 if (IS_ERR(xprt)) {
369 printk(KERN_WARNING "NFS: cannot create RPC transport.\n"); 385 dprintk("%s: cannot create RPC transport. Error = %ld\n",
386 __FUNCTION__, PTR_ERR(xprt));
370 return (struct rpc_clnt *)xprt; 387 return (struct rpc_clnt *)xprt;
371 } 388 }
372 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 389 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
373 server->rpc_ops->version, data->pseudoflavor); 390 server->rpc_ops->version, data->pseudoflavor);
374 if (IS_ERR(clnt)) { 391 if (IS_ERR(clnt)) {
375 printk(KERN_WARNING "NFS: cannot create RPC client.\n"); 392 dprintk("%s: cannot create RPC client. Error = %ld\n",
393 __FUNCTION__, PTR_ERR(xprt));
376 goto out_fail; 394 goto out_fail;
377 } 395 }
378 396
@@ -383,7 +401,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
383 return clnt; 401 return clnt;
384 402
385out_fail: 403out_fail:
386 xprt_destroy(xprt);
387 return clnt; 404 return clnt;
388} 405}
389 406
@@ -427,21 +444,16 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
427 444
428 /* Check NFS protocol revision and initialize RPC op vector 445 /* Check NFS protocol revision and initialize RPC op vector
429 * and file handle pool. */ 446 * and file handle pool. */
430 if (server->flags & NFS_MOUNT_VER3) {
431#ifdef CONFIG_NFS_V3 447#ifdef CONFIG_NFS_V3
448 if (server->flags & NFS_MOUNT_VER3) {
432 server->rpc_ops = &nfs_v3_clientops; 449 server->rpc_ops = &nfs_v3_clientops;
433 server->caps |= NFS_CAP_READDIRPLUS; 450 server->caps |= NFS_CAP_READDIRPLUS;
434 if (data->version < 4) {
435 printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
436 return -EIO;
437 }
438#else
439 printk(KERN_NOTICE "NFS: NFSv3 not supported.\n");
440 return -EIO;
441#endif
442 } else { 451 } else {
443 server->rpc_ops = &nfs_v2_clientops; 452 server->rpc_ops = &nfs_v2_clientops;
444 } 453 }
454#else
455 server->rpc_ops = &nfs_v2_clientops;
456#endif
445 457
446 /* Fill in pseudoflavor for mount version < 5 */ 458 /* Fill in pseudoflavor for mount version < 5 */
447 if (!(data->flags & NFS_MOUNT_SECFLAVOUR)) 459 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
@@ -455,17 +467,34 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
455 return PTR_ERR(server->client); 467 return PTR_ERR(server->client);
456 /* RFC 2623, sec 2.3.2 */ 468 /* RFC 2623, sec 2.3.2 */
457 if (authflavor != RPC_AUTH_UNIX) { 469 if (authflavor != RPC_AUTH_UNIX) {
470 struct rpc_auth *auth;
471
458 server->client_sys = rpc_clone_client(server->client); 472 server->client_sys = rpc_clone_client(server->client);
459 if (IS_ERR(server->client_sys)) 473 if (IS_ERR(server->client_sys))
460 return PTR_ERR(server->client_sys); 474 return PTR_ERR(server->client_sys);
461 if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys)) 475 auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
462 return -ENOMEM; 476 if (IS_ERR(auth))
477 return PTR_ERR(auth);
463 } else { 478 } else {
464 atomic_inc(&server->client->cl_count); 479 atomic_inc(&server->client->cl_count);
465 server->client_sys = server->client; 480 server->client_sys = server->client;
466 } 481 }
467
468 if (server->flags & NFS_MOUNT_VER3) { 482 if (server->flags & NFS_MOUNT_VER3) {
483#ifdef CONFIG_NFS_V3_ACL
484 if (!(server->flags & NFS_MOUNT_NOACL)) {
485 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
486 /* No errors! Assume that Sun nfsacls are supported */
487 if (!IS_ERR(server->client_acl))
488 server->caps |= NFS_CAP_ACLS;
489 }
490#else
491 server->flags &= ~NFS_MOUNT_NOACL;
492#endif /* CONFIG_NFS_V3_ACL */
493 /*
494 * The VFS shouldn't apply the umask to mode bits. We will
495 * do so ourselves when necessary.
496 */
497 sb->s_flags |= MS_POSIXACL;
469 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) 498 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
470 server->namelen = NFS3_MAXNAMLEN; 499 server->namelen = NFS3_MAXNAMLEN;
471 sb->s_time_gran = 1; 500 sb->s_time_gran = 1;
@@ -549,6 +578,7 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
549 { NFS_MOUNT_NOCTO, ",nocto", "" }, 578 { NFS_MOUNT_NOCTO, ",nocto", "" },
550 { NFS_MOUNT_NOAC, ",noac", "" }, 579 { NFS_MOUNT_NOAC, ",noac", "" },
551 { NFS_MOUNT_NONLM, ",nolock", ",lock" }, 580 { NFS_MOUNT_NONLM, ",nolock", ",lock" },
581 { NFS_MOUNT_NOACL, ",noacl", "" },
552 { 0, NULL, NULL } 582 { 0, NULL, NULL }
553 }; 583 };
554 struct proc_nfs_info *nfs_infop; 584 struct proc_nfs_info *nfs_infop;
@@ -590,9 +620,19 @@ nfs_zap_caches(struct inode *inode)
590 620
591 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); 621 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
592 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) 622 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
593 nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; 623 nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
594 else 624 else
595 nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; 625 nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
626}
627
628static void nfs_zap_acl_cache(struct inode *inode)
629{
630 void (*clear_acl_cache)(struct inode *);
631
632 clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
633 if (clear_acl_cache != NULL)
634 clear_acl_cache(inode);
635 NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL;
596} 636}
597 637
598/* 638/*
@@ -689,7 +729,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
689 /* Why so? Because we want revalidate for devices/FIFOs, and 729 /* Why so? Because we want revalidate for devices/FIFOs, and
690 * that's precisely what we have in nfs_file_inode_operations. 730 * that's precisely what we have in nfs_file_inode_operations.
691 */ 731 */
692 inode->i_op = &nfs_file_inode_operations; 732 inode->i_op = NFS_SB(sb)->rpc_ops->file_inode_ops;
693 if (S_ISREG(inode->i_mode)) { 733 if (S_ISREG(inode->i_mode)) {
694 inode->i_fop = &nfs_file_operations; 734 inode->i_fop = &nfs_file_operations;
695 inode->i_data.a_ops = &nfs_file_aops; 735 inode->i_data.a_ops = &nfs_file_aops;
@@ -792,7 +832,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
792 } 832 }
793 } 833 }
794 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) 834 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
795 NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; 835 NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
796 nfs_end_data_update(inode); 836 nfs_end_data_update(inode);
797 unlock_kernel(); 837 unlock_kernel();
798 return error; 838 return error;
@@ -851,7 +891,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rp
851 ctx->state = NULL; 891 ctx->state = NULL;
852 ctx->lockowner = current->files; 892 ctx->lockowner = current->files;
853 ctx->error = 0; 893 ctx->error = 0;
854 init_waitqueue_head(&ctx->waitq); 894 ctx->dir_cookie = 0;
855 } 895 }
856 return ctx; 896 return ctx;
857} 897}
@@ -1015,6 +1055,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1015 goto out; 1055 goto out;
1016 } 1056 }
1017 flags = nfsi->flags; 1057 flags = nfsi->flags;
1058 nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE;
1018 /* 1059 /*
1019 * We may need to keep the attributes marked as invalid if 1060 * We may need to keep the attributes marked as invalid if
1020 * we raced with nfs_end_attr_update(). 1061 * we raced with nfs_end_attr_update().
@@ -1022,21 +1063,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1022 if (verifier == nfsi->cache_change_attribute) 1063 if (verifier == nfsi->cache_change_attribute)
1023 nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1064 nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1024 /* Do the page cache invalidation */ 1065 /* Do the page cache invalidation */
1025 if (flags & NFS_INO_INVALID_DATA) { 1066 nfs_revalidate_mapping(inode, inode->i_mapping);
1026 if (S_ISREG(inode->i_mode)) { 1067 if (flags & NFS_INO_INVALID_ACL)
1027 if (filemap_fdatawrite(inode->i_mapping) == 0) 1068 nfs_zap_acl_cache(inode);
1028 filemap_fdatawait(inode->i_mapping);
1029 nfs_wb_all(inode);
1030 }
1031 nfsi->flags &= ~NFS_INO_INVALID_DATA;
1032 invalidate_inode_pages2(inode->i_mapping);
1033 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
1034 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
1035 inode->i_sb->s_id,
1036 (long long)NFS_FILEID(inode));
1037 /* This ensures we revalidate dentries */
1038 nfsi->cache_change_attribute++;
1039 }
1040 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", 1069 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
1041 inode->i_sb->s_id, 1070 inode->i_sb->s_id,
1042 (long long)NFS_FILEID(inode)); 1071 (long long)NFS_FILEID(inode));
@@ -1074,6 +1103,34 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1074} 1103}
1075 1104
1076/** 1105/**
1106 * nfs_revalidate_mapping - Revalidate the pagecache
1107 * @inode - pointer to host inode
1108 * @mapping - pointer to mapping
1109 */
1110void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
1111{
1112 struct nfs_inode *nfsi = NFS_I(inode);
1113
1114 if (nfsi->flags & NFS_INO_INVALID_DATA) {
1115 if (S_ISREG(inode->i_mode)) {
1116 if (filemap_fdatawrite(mapping) == 0)
1117 filemap_fdatawait(mapping);
1118 nfs_wb_all(inode);
1119 }
1120 invalidate_inode_pages2(mapping);
1121 nfsi->flags &= ~NFS_INO_INVALID_DATA;
1122 if (S_ISDIR(inode->i_mode)) {
1123 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
1124 /* This ensures we revalidate child dentries */
1125 nfsi->cache_change_attribute++;
1126 }
1127 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
1128 inode->i_sb->s_id,
1129 (long long)NFS_FILEID(inode));
1130 }
1131}
1132
1133/**
1077 * nfs_begin_data_update 1134 * nfs_begin_data_update
1078 * @inode - pointer to inode 1135 * @inode - pointer to inode
1079 * Declare that a set of operations will update file data on the server 1136 * Declare that a set of operations will update file data on the server
@@ -1106,27 +1163,6 @@ void nfs_end_data_update(struct inode *inode)
1106} 1163}
1107 1164
1108/** 1165/**
1109 * nfs_end_data_update_defer
1110 * @inode - pointer to inode
1111 * Declare end of the operations that will update file data
1112 * This will defer marking the inode as needing revalidation
1113 * unless there are no other pending updates.
1114 */
1115void nfs_end_data_update_defer(struct inode *inode)
1116{
1117 struct nfs_inode *nfsi = NFS_I(inode);
1118
1119 if (atomic_dec_and_test(&nfsi->data_updates)) {
1120 /* Mark the attribute cache for revalidation */
1121 nfsi->flags |= NFS_INO_INVALID_ATTR;
1122 /* Directories and symlinks: invalidate page cache too */
1123 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
1124 nfsi->flags |= NFS_INO_INVALID_DATA;
1125 nfsi->cache_change_attribute ++;
1126 }
1127}
1128
1129/**
1130 * nfs_refresh_inode - verify consistency of the inode attribute cache 1166 * nfs_refresh_inode - verify consistency of the inode attribute cache
1131 * @inode - pointer to inode 1167 * @inode - pointer to inode
1132 * @fattr - updated attributes 1168 * @fattr - updated attributes
@@ -1152,8 +1188,11 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1152 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 1188 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
1153 && nfsi->change_attr == fattr->pre_change_attr) 1189 && nfsi->change_attr == fattr->pre_change_attr)
1154 nfsi->change_attr = fattr->change_attr; 1190 nfsi->change_attr = fattr->change_attr;
1155 if (!data_unstable && nfsi->change_attr != fattr->change_attr) 1191 if (nfsi->change_attr != fattr->change_attr) {
1156 nfsi->flags |= NFS_INO_INVALID_ATTR; 1192 nfsi->flags |= NFS_INO_INVALID_ATTR;
1193 if (!data_unstable)
1194 nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
1195 }
1157 } 1196 }
1158 1197
1159 if ((fattr->valid & NFS_ATTR_FATTR) == 0) 1198 if ((fattr->valid & NFS_ATTR_FATTR) == 0)
@@ -1176,18 +1215,22 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1176 } 1215 }
1177 1216
1178 /* Verify a few of the more important attributes */ 1217 /* Verify a few of the more important attributes */
1179 if (!data_unstable) { 1218 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
1180 if (!timespec_equal(&inode->i_mtime, &fattr->mtime) 1219 nfsi->flags |= NFS_INO_INVALID_ATTR;
1181 || cur_size != new_isize) 1220 if (!data_unstable)
1182 nfsi->flags |= NFS_INO_INVALID_ATTR; 1221 nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
1183 } else if (S_ISREG(inode->i_mode) && new_isize > cur_size) 1222 }
1184 nfsi->flags |= NFS_INO_INVALID_ATTR; 1223 if (cur_size != new_isize) {
1224 nfsi->flags |= NFS_INO_INVALID_ATTR;
1225 if (nfsi->npages == 0)
1226 nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
1227 }
1185 1228
1186 /* Have any file permissions changed? */ 1229 /* Have any file permissions changed? */
1187 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) 1230 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
1188 || inode->i_uid != fattr->uid 1231 || inode->i_uid != fattr->uid
1189 || inode->i_gid != fattr->gid) 1232 || inode->i_gid != fattr->gid)
1190 nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; 1233 nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
1191 1234
1192 /* Has the link count changed? */ 1235 /* Has the link count changed? */
1193 if (inode->i_nlink != fattr->nlink) 1236 if (inode->i_nlink != fattr->nlink)
@@ -1215,10 +1258,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1215static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) 1258static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier)
1216{ 1259{
1217 struct nfs_inode *nfsi = NFS_I(inode); 1260 struct nfs_inode *nfsi = NFS_I(inode);
1218 __u64 new_size; 1261 loff_t cur_isize, new_isize;
1219 loff_t new_isize;
1220 unsigned int invalid = 0; 1262 unsigned int invalid = 0;
1221 loff_t cur_isize;
1222 int data_unstable; 1263 int data_unstable;
1223 1264
1224 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 1265 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
@@ -1251,61 +1292,56 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1251 /* Are we racing with known updates of the metadata on the server? */ 1292 /* Are we racing with known updates of the metadata on the server? */
1252 data_unstable = ! nfs_verify_change_attribute(inode, verifier); 1293 data_unstable = ! nfs_verify_change_attribute(inode, verifier);
1253 1294
1254 /* Check if the file size agrees */ 1295 /* Check if our cached file size is stale */
1255 new_size = fattr->size;
1256 new_isize = nfs_size_to_loff_t(fattr->size); 1296 new_isize = nfs_size_to_loff_t(fattr->size);
1257 cur_isize = i_size_read(inode); 1297 cur_isize = i_size_read(inode);
1258 if (cur_isize != new_size) { 1298 if (new_isize != cur_isize) {
1259#ifdef NFS_DEBUG_VERBOSE 1299 /* Do we perhaps have any outstanding writes? */
1260 printk(KERN_DEBUG "NFS: isize change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); 1300 if (nfsi->npages == 0) {
1261#endif 1301 /* No, but did we race with nfs_end_data_update()? */
1262 /* 1302 if (verifier == nfsi->cache_change_attribute) {
1263 * If we have pending writebacks, things can get
1264 * messy.
1265 */
1266 if (S_ISREG(inode->i_mode) && data_unstable) {
1267 if (new_isize > cur_isize) {
1268 inode->i_size = new_isize; 1303 inode->i_size = new_isize;
1269 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1304 invalid |= NFS_INO_INVALID_DATA;
1270 } 1305 }
1271 } else { 1306 invalid |= NFS_INO_INVALID_ATTR;
1307 } else if (new_isize > cur_isize) {
1272 inode->i_size = new_isize; 1308 inode->i_size = new_isize;
1273 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1309 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1274 } 1310 }
1311 dprintk("NFS: isize change on server for file %s/%ld\n",
1312 inode->i_sb->s_id, inode->i_ino);
1275 } 1313 }
1276 1314
1277 /* 1315 /* Check if the mtime agrees */
1278 * Note: we don't check inode->i_mtime since pipes etc.
1279 * can change this value in VFS without requiring a
1280 * cache revalidation.
1281 */
1282 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { 1316 if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
1283 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1317 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1284#ifdef NFS_DEBUG_VERBOSE 1318 dprintk("NFS: mtime change on server for file %s/%ld\n",
1285 printk(KERN_DEBUG "NFS: mtime change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino); 1319 inode->i_sb->s_id, inode->i_ino);
1286#endif
1287 if (!data_unstable) 1320 if (!data_unstable)
1288 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1321 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1289 } 1322 }
1290 1323
1291 if ((fattr->valid & NFS_ATTR_FATTR_V4) 1324 if ((fattr->valid & NFS_ATTR_FATTR_V4)
1292 && nfsi->change_attr != fattr->change_attr) { 1325 && nfsi->change_attr != fattr->change_attr) {
1293#ifdef NFS_DEBUG_VERBOSE 1326 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1294 printk(KERN_DEBUG "NFS: change_attr change on %s/%ld\n",
1295 inode->i_sb->s_id, inode->i_ino); 1327 inode->i_sb->s_id, inode->i_ino);
1296#endif
1297 nfsi->change_attr = fattr->change_attr; 1328 nfsi->change_attr = fattr->change_attr;
1298 if (!data_unstable) 1329 if (!data_unstable)
1299 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS; 1330 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1300 } 1331 }
1301 1332
1302 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1333 /* If ctime has changed we should definitely clear access+acl caches */
1334 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1335 if (!data_unstable)
1336 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1337 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1338 }
1303 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1339 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1304 1340
1305 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || 1341 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
1306 inode->i_uid != fattr->uid || 1342 inode->i_uid != fattr->uid ||
1307 inode->i_gid != fattr->gid) 1343 inode->i_gid != fattr->gid)
1308 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS; 1344 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1309 1345
1310 inode->i_mode = fattr->mode; 1346 inode->i_mode = fattr->mode;
1311 inode->i_nlink = fattr->nlink; 1347 inode->i_nlink = fattr->nlink;
@@ -1385,74 +1421,95 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1385 int flags, const char *dev_name, void *raw_data) 1421 int flags, const char *dev_name, void *raw_data)
1386{ 1422{
1387 int error; 1423 int error;
1388 struct nfs_server *server; 1424 struct nfs_server *server = NULL;
1389 struct super_block *s; 1425 struct super_block *s;
1390 struct nfs_fh *root; 1426 struct nfs_fh *root;
1391 struct nfs_mount_data *data = raw_data; 1427 struct nfs_mount_data *data = raw_data;
1392 1428
1393 if (!data) { 1429 s = ERR_PTR(-EINVAL);
1394 printk("nfs_read_super: missing data argument\n"); 1430 if (data == NULL) {
1395 return ERR_PTR(-EINVAL); 1431 dprintk("%s: missing data argument\n", __FUNCTION__);
1432 goto out_err;
1433 }
1434 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
1435 dprintk("%s: bad mount version\n", __FUNCTION__);
1436 goto out_err;
1396 } 1437 }
1438 switch (data->version) {
1439 case 1:
1440 data->namlen = 0;
1441 case 2:
1442 data->bsize = 0;
1443 case 3:
1444 if (data->flags & NFS_MOUNT_VER3) {
1445 dprintk("%s: mount structure version %d does not support NFSv3\n",
1446 __FUNCTION__,
1447 data->version);
1448 goto out_err;
1449 }
1450 data->root.size = NFS2_FHSIZE;
1451 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1452 case 4:
1453 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
1454 dprintk("%s: mount structure version %d does not support strong security\n",
1455 __FUNCTION__,
1456 data->version);
1457 goto out_err;
1458 }
1459 case 5:
1460 memset(data->context, 0, sizeof(data->context));
1461 }
1462#ifndef CONFIG_NFS_V3
1463 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
1464 s = ERR_PTR(-EPROTONOSUPPORT);
1465 if (data->flags & NFS_MOUNT_VER3) {
1466 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
1467 goto out_err;
1468 }
1469#endif /* CONFIG_NFS_V3 */
1397 1470
1471 s = ERR_PTR(-ENOMEM);
1398 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 1472 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
1399 if (!server) 1473 if (!server)
1400 return ERR_PTR(-ENOMEM); 1474 goto out_err;
1401 memset(server, 0, sizeof(struct nfs_server)); 1475 memset(server, 0, sizeof(struct nfs_server));
1402 /* Zero out the NFS state stuff */ 1476 /* Zero out the NFS state stuff */
1403 init_nfsv4_state(server); 1477 init_nfsv4_state(server);
1404 1478 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1405 if (data->version != NFS_MOUNT_VERSION) {
1406 printk("nfs warning: mount version %s than kernel\n",
1407 data->version < NFS_MOUNT_VERSION ? "older" : "newer");
1408 if (data->version < 2)
1409 data->namlen = 0;
1410 if (data->version < 3)
1411 data->bsize = 0;
1412 if (data->version < 4) {
1413 data->flags &= ~NFS_MOUNT_VER3;
1414 data->root.size = NFS2_FHSIZE;
1415 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1416 }
1417 if (data->version < 5)
1418 data->flags &= ~NFS_MOUNT_SECFLAVOUR;
1419 }
1420 1479
1421 root = &server->fh; 1480 root = &server->fh;
1422 if (data->flags & NFS_MOUNT_VER3) 1481 if (data->flags & NFS_MOUNT_VER3)
1423 root->size = data->root.size; 1482 root->size = data->root.size;
1424 else 1483 else
1425 root->size = NFS2_FHSIZE; 1484 root->size = NFS2_FHSIZE;
1485 s = ERR_PTR(-EINVAL);
1426 if (root->size > sizeof(root->data)) { 1486 if (root->size > sizeof(root->data)) {
1427 printk("nfs_get_sb: invalid root filehandle\n"); 1487 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1428 kfree(server); 1488 goto out_err;
1429 return ERR_PTR(-EINVAL);
1430 } 1489 }
1431 memcpy(root->data, data->root.data, root->size); 1490 memcpy(root->data, data->root.data, root->size);
1432 1491
1433 /* We now require that the mount process passes the remote address */ 1492 /* We now require that the mount process passes the remote address */
1434 memcpy(&server->addr, &data->addr, sizeof(server->addr)); 1493 memcpy(&server->addr, &data->addr, sizeof(server->addr));
1435 if (server->addr.sin_addr.s_addr == INADDR_ANY) { 1494 if (server->addr.sin_addr.s_addr == INADDR_ANY) {
1436 printk("NFS: mount program didn't pass remote address!\n"); 1495 dprintk("%s: mount program didn't pass remote address!\n",
1437 kfree(server); 1496 __FUNCTION__);
1438 return ERR_PTR(-EINVAL); 1497 goto out_err;
1439 } 1498 }
1440 1499
1441 s = sget(fs_type, nfs_compare_super, nfs_set_super, server); 1500 /* Fire up rpciod if not yet running */
1442 1501 s = ERR_PTR(rpciod_up());
1443 if (IS_ERR(s) || s->s_root) { 1502 if (IS_ERR(s)) {
1444 kfree(server); 1503 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1445 return s; 1504 __FUNCTION__, PTR_ERR(s));
1505 goto out_err;
1446 } 1506 }
1447 1507
1448 s->s_flags = flags; 1508 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1509 if (IS_ERR(s) || s->s_root)
1510 goto out_rpciod_down;
1449 1511
1450 /* Fire up rpciod if not yet running */ 1512 s->s_flags = flags;
1451 if (rpciod_up() != 0) {
1452 printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
1453 kfree(server);
1454 return ERR_PTR(-EIO);
1455 }
1456 1513
1457 error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); 1514 error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
1458 if (error) { 1515 if (error) {
@@ -1462,6 +1519,11 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1462 } 1519 }
1463 s->s_flags |= MS_ACTIVE; 1520 s->s_flags |= MS_ACTIVE;
1464 return s; 1521 return s;
1522out_rpciod_down:
1523 rpciod_down();
1524out_err:
1525 kfree(server);
1526 return s;
1465} 1527}
1466 1528
1467static void nfs_kill_super(struct super_block *s) 1529static void nfs_kill_super(struct super_block *s)
@@ -1470,10 +1532,12 @@ static void nfs_kill_super(struct super_block *s)
1470 1532
1471 kill_anon_super(s); 1533 kill_anon_super(s);
1472 1534
1473 if (server->client != NULL && !IS_ERR(server->client)) 1535 if (!IS_ERR(server->client))
1474 rpc_shutdown_client(server->client); 1536 rpc_shutdown_client(server->client);
1475 if (server->client_sys != NULL && !IS_ERR(server->client_sys)) 1537 if (!IS_ERR(server->client_sys))
1476 rpc_shutdown_client(server->client_sys); 1538 rpc_shutdown_client(server->client_sys);
1539 if (!IS_ERR(server->client_acl))
1540 rpc_shutdown_client(server->client_acl);
1477 1541
1478 if (!(server->flags & NFS_MOUNT_NONLM)) 1542 if (!(server->flags & NFS_MOUNT_NONLM))
1479 lockd_down(); /* release rpc.lockd */ 1543 lockd_down(); /* release rpc.lockd */
@@ -1594,15 +1658,19 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1594 1658
1595 clp = nfs4_get_client(&server->addr.sin_addr); 1659 clp = nfs4_get_client(&server->addr.sin_addr);
1596 if (!clp) { 1660 if (!clp) {
1597 printk(KERN_WARNING "NFS: failed to create NFS4 client.\n"); 1661 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
1598 return -EIO; 1662 return -EIO;
1599 } 1663 }
1600 1664
1601 /* Now create transport and client */ 1665 /* Now create transport and client */
1602 authflavour = RPC_AUTH_UNIX; 1666 authflavour = RPC_AUTH_UNIX;
1603 if (data->auth_flavourlen != 0) { 1667 if (data->auth_flavourlen != 0) {
1604 if (data->auth_flavourlen > 1) 1668 if (data->auth_flavourlen != 1) {
1605 printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n"); 1669 dprintk("%s: Invalid number of RPC auth flavours %d.\n",
1670 __FUNCTION__, data->auth_flavourlen);
1671 err = -EINVAL;
1672 goto out_fail;
1673 }
1606 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) { 1674 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
1607 err = -EFAULT; 1675 err = -EFAULT;
1608 goto out_fail; 1676 goto out_fail;
@@ -1610,21 +1678,22 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1610 } 1678 }
1611 1679
1612 down_write(&clp->cl_sem); 1680 down_write(&clp->cl_sem);
1613 if (clp->cl_rpcclient == NULL) { 1681 if (IS_ERR(clp->cl_rpcclient)) {
1614 xprt = xprt_create_proto(proto, &server->addr, &timeparms); 1682 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
1615 if (IS_ERR(xprt)) { 1683 if (IS_ERR(xprt)) {
1616 up_write(&clp->cl_sem); 1684 up_write(&clp->cl_sem);
1617 printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
1618 err = PTR_ERR(xprt); 1685 err = PTR_ERR(xprt);
1686 dprintk("%s: cannot create RPC transport. Error = %d\n",
1687 __FUNCTION__, err);
1619 goto out_fail; 1688 goto out_fail;
1620 } 1689 }
1621 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 1690 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1622 server->rpc_ops->version, authflavour); 1691 server->rpc_ops->version, authflavour);
1623 if (IS_ERR(clnt)) { 1692 if (IS_ERR(clnt)) {
1624 up_write(&clp->cl_sem); 1693 up_write(&clp->cl_sem);
1625 printk(KERN_WARNING "NFS: cannot create RPC client.\n");
1626 xprt_destroy(xprt);
1627 err = PTR_ERR(clnt); 1694 err = PTR_ERR(clnt);
1695 dprintk("%s: cannot create RPC client. Error = %d\n",
1696 __FUNCTION__, err);
1628 goto out_fail; 1697 goto out_fail;
1629 } 1698 }
1630 clnt->cl_intr = 1; 1699 clnt->cl_intr = 1;
@@ -1656,21 +1725,26 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1656 clp = NULL; 1725 clp = NULL;
1657 1726
1658 if (IS_ERR(clnt)) { 1727 if (IS_ERR(clnt)) {
1659 printk(KERN_WARNING "NFS: cannot create RPC client.\n"); 1728 err = PTR_ERR(clnt);
1660 return PTR_ERR(clnt); 1729 dprintk("%s: cannot create RPC client. Error = %d\n",
1730 __FUNCTION__, err);
1731 return err;
1661 } 1732 }
1662 1733
1663 server->client = clnt; 1734 server->client = clnt;
1664 1735
1665 if (server->nfs4_state->cl_idmap == NULL) { 1736 if (server->nfs4_state->cl_idmap == NULL) {
1666 printk(KERN_WARNING "NFS: failed to create idmapper.\n"); 1737 dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
1667 return -ENOMEM; 1738 return -ENOMEM;
1668 } 1739 }
1669 1740
1670 if (clnt->cl_auth->au_flavor != authflavour) { 1741 if (clnt->cl_auth->au_flavor != authflavour) {
1671 if (rpcauth_create(authflavour, clnt) == NULL) { 1742 struct rpc_auth *auth;
1672 printk(KERN_WARNING "NFS: couldn't create credcache!\n"); 1743
1673 return -ENOMEM; 1744 auth = rpcauth_create(authflavour, clnt);
1745 if (IS_ERR(auth)) {
1746 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
1747 return PTR_ERR(auth);
1674 } 1748 }
1675 } 1749 }
1676 1750
@@ -1730,8 +1804,12 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1730 struct nfs4_mount_data *data = raw_data; 1804 struct nfs4_mount_data *data = raw_data;
1731 void *p; 1805 void *p;
1732 1806
1733 if (!data) { 1807 if (data == NULL) {
1734 printk("nfs_read_super: missing data argument\n"); 1808 dprintk("%s: missing data argument\n", __FUNCTION__);
1809 return ERR_PTR(-EINVAL);
1810 }
1811 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
1812 dprintk("%s: bad mount version\n", __FUNCTION__);
1735 return ERR_PTR(-EINVAL); 1813 return ERR_PTR(-EINVAL);
1736 } 1814 }
1737 1815
@@ -1741,11 +1819,7 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1741 memset(server, 0, sizeof(struct nfs_server)); 1819 memset(server, 0, sizeof(struct nfs_server));
1742 /* Zero out the NFS state stuff */ 1820 /* Zero out the NFS state stuff */
1743 init_nfsv4_state(server); 1821 init_nfsv4_state(server);
1744 1822 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1745 if (data->version != NFS4_MOUNT_VERSION) {
1746 printk("nfs warning: mount version %s than kernel\n",
1747 data->version < NFS4_MOUNT_VERSION ? "older" : "newer");
1748 }
1749 1823
1750 p = nfs_copy_user_string(NULL, &data->hostname, 256); 1824 p = nfs_copy_user_string(NULL, &data->hostname, 256);
1751 if (IS_ERR(p)) 1825 if (IS_ERR(p))
@@ -1773,11 +1847,20 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1773 } 1847 }
1774 if (server->addr.sin_family != AF_INET || 1848 if (server->addr.sin_family != AF_INET ||
1775 server->addr.sin_addr.s_addr == INADDR_ANY) { 1849 server->addr.sin_addr.s_addr == INADDR_ANY) {
1776 printk("NFS: mount program didn't pass remote IP address!\n"); 1850 dprintk("%s: mount program didn't pass remote IP address!\n",
1851 __FUNCTION__);
1777 s = ERR_PTR(-EINVAL); 1852 s = ERR_PTR(-EINVAL);
1778 goto out_free; 1853 goto out_free;
1779 } 1854 }
1780 1855
1856 /* Fire up rpciod if not yet running */
1857 s = ERR_PTR(rpciod_up());
1858 if (IS_ERR(s)) {
1859 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1860 __FUNCTION__, PTR_ERR(s));
1861 goto out_free;
1862 }
1863
1781 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 1864 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
1782 1865
1783 if (IS_ERR(s) || s->s_root) 1866 if (IS_ERR(s) || s->s_root)
@@ -1785,13 +1868,6 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1785 1868
1786 s->s_flags = flags; 1869 s->s_flags = flags;
1787 1870
1788 /* Fire up rpciod if not yet running */
1789 if (rpciod_up() != 0) {
1790 printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
1791 s = ERR_PTR(-EIO);
1792 goto out_free;
1793 }
1794
1795 error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); 1871 error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
1796 if (error) { 1872 if (error) {
1797 up_write(&s->s_umount); 1873 up_write(&s->s_umount);
@@ -1875,6 +1951,13 @@ static struct inode *nfs_alloc_inode(struct super_block *sb)
1875 if (!nfsi) 1951 if (!nfsi)
1876 return NULL; 1952 return NULL;
1877 nfsi->flags = 0; 1953 nfsi->flags = 0;
1954#ifdef CONFIG_NFS_V3_ACL
1955 nfsi->acl_access = ERR_PTR(-EAGAIN);
1956 nfsi->acl_default = ERR_PTR(-EAGAIN);
1957#endif
1958#ifdef CONFIG_NFS_V4
1959 nfsi->nfs4_acl = NULL;
1960#endif /* CONFIG_NFS_V4 */
1878 return &nfsi->vfs_inode; 1961 return &nfsi->vfs_inode;
1879} 1962}
1880 1963
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 9d3ddad96d9e..0e82617f2de0 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -80,9 +80,7 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
80 clnt = rpc_create_client(xprt, hostname, 80 clnt = rpc_create_client(xprt, hostname,
81 &mnt_program, version, 81 &mnt_program, version,
82 RPC_AUTH_UNIX); 82 RPC_AUTH_UNIX);
83 if (IS_ERR(clnt)) { 83 if (!IS_ERR(clnt)) {
84 xprt_destroy(xprt);
85 } else {
86 clnt->cl_softrtry = 1; 84 clnt->cl_softrtry = 1;
87 clnt->cl_chatty = 1; 85 clnt->cl_chatty = 1;
88 clnt->cl_oneshot = 1; 86 clnt->cl_oneshot = 1;
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
new file mode 100644
index 000000000000..ee3536fc84a3
--- /dev/null
+++ b/fs/nfs/nfs3acl.c
@@ -0,0 +1,403 @@
1#include <linux/fs.h>
2#include <linux/nfs.h>
3#include <linux/nfs3.h>
4#include <linux/nfs_fs.h>
5#include <linux/xattr_acl.h>
6#include <linux/nfsacl.h>
7
8#define NFSDBG_FACILITY NFSDBG_PROC
9
10ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
11{
12 struct inode *inode = dentry->d_inode;
13 struct posix_acl *acl;
14 int pos=0, len=0;
15
16# define output(s) do { \
17 if (pos + sizeof(s) <= size) { \
18 memcpy(buffer + pos, s, sizeof(s)); \
19 pos += sizeof(s); \
20 } \
21 len += sizeof(s); \
22 } while(0)
23
24 acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS);
25 if (IS_ERR(acl))
26 return PTR_ERR(acl);
27 if (acl) {
28 output("system.posix_acl_access");
29 posix_acl_release(acl);
30 }
31
32 if (S_ISDIR(inode->i_mode)) {
33 acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT);
34 if (IS_ERR(acl))
35 return PTR_ERR(acl);
36 if (acl) {
37 output("system.posix_acl_default");
38 posix_acl_release(acl);
39 }
40 }
41
42# undef output
43
44 if (!buffer || len <= size)
45 return len;
46 return -ERANGE;
47}
48
49ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
50 void *buffer, size_t size)
51{
52 struct inode *inode = dentry->d_inode;
53 struct posix_acl *acl;
54 int type, error = 0;
55
56 if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
57 type = ACL_TYPE_ACCESS;
58 else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
59 type = ACL_TYPE_DEFAULT;
60 else
61 return -EOPNOTSUPP;
62
63 acl = nfs3_proc_getacl(inode, type);
64 if (IS_ERR(acl))
65 return PTR_ERR(acl);
66 else if (acl) {
67 if (type == ACL_TYPE_ACCESS && acl->a_count == 0)
68 error = -ENODATA;
69 else
70 error = posix_acl_to_xattr(acl, buffer, size);
71 posix_acl_release(acl);
72 } else
73 error = -ENODATA;
74
75 return error;
76}
77
78int nfs3_setxattr(struct dentry *dentry, const char *name,
79 const void *value, size_t size, int flags)
80{
81 struct inode *inode = dentry->d_inode;
82 struct posix_acl *acl;
83 int type, error;
84
85 if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
86 type = ACL_TYPE_ACCESS;
87 else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
88 type = ACL_TYPE_DEFAULT;
89 else
90 return -EOPNOTSUPP;
91
92 acl = posix_acl_from_xattr(value, size);
93 if (IS_ERR(acl))
94 return PTR_ERR(acl);
95 error = nfs3_proc_setacl(inode, type, acl);
96 posix_acl_release(acl);
97
98 return error;
99}
100
101int nfs3_removexattr(struct dentry *dentry, const char *name)
102{
103 struct inode *inode = dentry->d_inode;
104 int type;
105
106 if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
107 type = ACL_TYPE_ACCESS;
108 else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
109 type = ACL_TYPE_DEFAULT;
110 else
111 return -EOPNOTSUPP;
112
113 return nfs3_proc_setacl(inode, type, NULL);
114}
115
116static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
117{
118 if (!IS_ERR(nfsi->acl_access)) {
119 posix_acl_release(nfsi->acl_access);
120 nfsi->acl_access = ERR_PTR(-EAGAIN);
121 }
122 if (!IS_ERR(nfsi->acl_default)) {
123 posix_acl_release(nfsi->acl_default);
124 nfsi->acl_default = ERR_PTR(-EAGAIN);
125 }
126}
127
128void nfs3_forget_cached_acls(struct inode *inode)
129{
130 dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id,
131 inode->i_ino);
132 spin_lock(&inode->i_lock);
133 __nfs3_forget_cached_acls(NFS_I(inode));
134 spin_unlock(&inode->i_lock);
135}
136
137static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
138{
139 struct nfs_inode *nfsi = NFS_I(inode);
140 struct posix_acl *acl = ERR_PTR(-EINVAL);
141
142 spin_lock(&inode->i_lock);
143 switch(type) {
144 case ACL_TYPE_ACCESS:
145 acl = nfsi->acl_access;
146 break;
147
148 case ACL_TYPE_DEFAULT:
149 acl = nfsi->acl_default;
150 break;
151
152 default:
153 goto out;
154 }
155 if (IS_ERR(acl))
156 acl = ERR_PTR(-EAGAIN);
157 else
158 acl = posix_acl_dup(acl);
159out:
160 spin_unlock(&inode->i_lock);
161 dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
162 inode->i_ino, type, acl);
163 return acl;
164}
165
166static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
167 struct posix_acl *dfacl)
168{
169 struct nfs_inode *nfsi = NFS_I(inode);
170
171 dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id,
172 inode->i_ino, acl, dfacl);
173 spin_lock(&inode->i_lock);
174 __nfs3_forget_cached_acls(NFS_I(inode));
175 nfsi->acl_access = posix_acl_dup(acl);
176 nfsi->acl_default = posix_acl_dup(dfacl);
177 spin_unlock(&inode->i_lock);
178}
179
180struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
181{
182 struct nfs_server *server = NFS_SERVER(inode);
183 struct nfs_fattr fattr;
184 struct page *pages[NFSACL_MAXPAGES] = { };
185 struct nfs3_getaclargs args = {
186 .fh = NFS_FH(inode),
187 /* The xdr layer may allocate pages here. */
188 .pages = pages,
189 };
190 struct nfs3_getaclres res = {
191 .fattr = &fattr,
192 };
193 struct posix_acl *acl;
194 int status, count;
195
196 if (!nfs_server_capable(inode, NFS_CAP_ACLS))
197 return ERR_PTR(-EOPNOTSUPP);
198
199 status = nfs_revalidate_inode(server, inode);
200 if (status < 0)
201 return ERR_PTR(status);
202 acl = nfs3_get_cached_acl(inode, type);
203 if (acl != ERR_PTR(-EAGAIN))
204 return acl;
205 acl = NULL;
206
207 /*
208 * Only get the access acl when explicitly requested: We don't
209 * need it for access decisions, and only some applications use
210 * it. Applications which request the access acl first are not
211 * penalized from this optimization.
212 */
213 if (type == ACL_TYPE_ACCESS)
214 args.mask |= NFS_ACLCNT|NFS_ACL;
215 if (S_ISDIR(inode->i_mode))
216 args.mask |= NFS_DFACLCNT|NFS_DFACL;
217 if (args.mask == 0)
218 return NULL;
219
220 dprintk("NFS call getacl\n");
221 status = rpc_call(server->client_acl, ACLPROC3_GETACL,
222 &args, &res, 0);
223 dprintk("NFS reply getacl: %d\n", status);
224
225 /* pages may have been allocated at the xdr layer. */
226 for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
227 __free_page(args.pages[count]);
228
229 switch (status) {
230 case 0:
231 status = nfs_refresh_inode(inode, &fattr);
232 break;
233 case -EPFNOSUPPORT:
234 case -EPROTONOSUPPORT:
235 dprintk("NFS_V3_ACL extension not supported; disabling\n");
236 server->caps &= ~NFS_CAP_ACLS;
237 case -ENOTSUPP:
238 status = -EOPNOTSUPP;
239 default:
240 goto getout;
241 }
242 if ((args.mask & res.mask) != args.mask) {
243 status = -EIO;
244 goto getout;
245 }
246
247 if (res.acl_access != NULL) {
248 if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) {
249 posix_acl_release(res.acl_access);
250 res.acl_access = NULL;
251 }
252 }
253 nfs3_cache_acls(inode, res.acl_access, res.acl_default);
254
255 switch(type) {
256 case ACL_TYPE_ACCESS:
257 acl = res.acl_access;
258 res.acl_access = NULL;
259 break;
260
261 case ACL_TYPE_DEFAULT:
262 acl = res.acl_default;
263 res.acl_default = NULL;
264 }
265
266getout:
267 posix_acl_release(res.acl_access);
268 posix_acl_release(res.acl_default);
269
270 if (status != 0) {
271 posix_acl_release(acl);
272 acl = ERR_PTR(status);
273 }
274 return acl;
275}
276
277static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
278 struct posix_acl *dfacl)
279{
280 struct nfs_server *server = NFS_SERVER(inode);
281 struct nfs_fattr fattr;
282 struct page *pages[NFSACL_MAXPAGES] = { };
283 struct nfs3_setaclargs args = {
284 .inode = inode,
285 .mask = NFS_ACL,
286 .acl_access = acl,
287 .pages = pages,
288 };
289 int status, count;
290
291 status = -EOPNOTSUPP;
292 if (!nfs_server_capable(inode, NFS_CAP_ACLS))
293 goto out;
294
295 /* We are doing this here, because XDR marshalling can only
296 return -ENOMEM. */
297 status = -ENOSPC;
298 if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
299 goto out;
300 if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES)
301 goto out;
302 if (S_ISDIR(inode->i_mode)) {
303 args.mask |= NFS_DFACL;
304 args.acl_default = dfacl;
305 }
306
307 dprintk("NFS call setacl\n");
308 nfs_begin_data_update(inode);
309 status = rpc_call(server->client_acl, ACLPROC3_SETACL,
310 &args, &fattr, 0);
311 NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS;
312 nfs_end_data_update(inode);
313 dprintk("NFS reply setacl: %d\n", status);
314
315 /* pages may have been allocated at the xdr layer. */
316 for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
317 __free_page(args.pages[count]);
318
319 switch (status) {
320 case 0:
321 status = nfs_refresh_inode(inode, &fattr);
322 break;
323 case -EPFNOSUPPORT:
324 case -EPROTONOSUPPORT:
325 dprintk("NFS_V3_ACL SETACL RPC not supported"
326 "(will not retry)\n");
327 server->caps &= ~NFS_CAP_ACLS;
328 case -ENOTSUPP:
329 status = -EOPNOTSUPP;
330 }
331out:
332 return status;
333}
334
335int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
336{
337 struct posix_acl *alloc = NULL, *dfacl = NULL;
338 int status;
339
340 if (S_ISDIR(inode->i_mode)) {
341 switch(type) {
342 case ACL_TYPE_ACCESS:
343 alloc = dfacl = nfs3_proc_getacl(inode,
344 ACL_TYPE_DEFAULT);
345 if (IS_ERR(alloc))
346 goto fail;
347 break;
348
349 case ACL_TYPE_DEFAULT:
350 dfacl = acl;
351 alloc = acl = nfs3_proc_getacl(inode,
352 ACL_TYPE_ACCESS);
353 if (IS_ERR(alloc))
354 goto fail;
355 break;
356
357 default:
358 return -EINVAL;
359 }
360 } else if (type != ACL_TYPE_ACCESS)
361 return -EINVAL;
362
363 if (acl == NULL) {
364 alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
365 if (IS_ERR(alloc))
366 goto fail;
367 }
368 status = nfs3_proc_setacls(inode, acl, dfacl);
369 posix_acl_release(alloc);
370 return status;
371
372fail:
373 return PTR_ERR(alloc);
374}
375
376int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
377 mode_t mode)
378{
379 struct posix_acl *dfacl, *acl;
380 int error = 0;
381
382 dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT);
383 if (IS_ERR(dfacl)) {
384 error = PTR_ERR(dfacl);
385 return (error == -EOPNOTSUPP) ? 0 : error;
386 }
387 if (!dfacl)
388 return 0;
389 acl = posix_acl_clone(dfacl, GFP_KERNEL);
390 error = -ENOMEM;
391 if (!acl)
392 goto out_release_dfacl;
393 error = posix_acl_create_masq(acl, &mode);
394 if (error < 0)
395 goto out_release_acl;
396 error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
397 dfacl : NULL);
398out_release_acl:
399 posix_acl_release(acl);
400out_release_dfacl:
401 posix_acl_release(dfacl);
402 return error;
403}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 3878494dfc2c..7851569b31c6 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -17,6 +17,7 @@
17#include <linux/nfs_page.h> 17#include <linux/nfs_page.h>
18#include <linux/lockd/bind.h> 18#include <linux/lockd/bind.h>
19#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
20#include <linux/nfs_mount.h>
20 21
21#define NFSDBG_FACILITY NFSDBG_PROC 22#define NFSDBG_FACILITY NFSDBG_PROC
22 23
@@ -45,7 +46,7 @@ static inline int
45nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags) 46nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
46{ 47{
47 struct rpc_message msg = { 48 struct rpc_message msg = {
48 .rpc_proc = &nfs3_procedures[proc], 49 .rpc_proc = &clnt->cl_procinfo[proc],
49 .rpc_argp = argp, 50 .rpc_argp = argp,
50 .rpc_resp = resp, 51 .rpc_resp = resp,
51 }; 52 };
@@ -313,7 +314,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
313 .fh = &fhandle, 314 .fh = &fhandle,
314 .fattr = &fattr 315 .fattr = &fattr
315 }; 316 };
316 int status; 317 mode_t mode = sattr->ia_mode;
318 int status;
317 319
318 dprintk("NFS call create %s\n", dentry->d_name.name); 320 dprintk("NFS call create %s\n", dentry->d_name.name);
319 arg.createmode = NFS3_CREATE_UNCHECKED; 321 arg.createmode = NFS3_CREATE_UNCHECKED;
@@ -323,6 +325,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
323 arg.verifier[1] = current->pid; 325 arg.verifier[1] = current->pid;
324 } 326 }
325 327
328 sattr->ia_mode &= ~current->fs->umask;
329
326again: 330again:
327 dir_attr.valid = 0; 331 dir_attr.valid = 0;
328 fattr.valid = 0; 332 fattr.valid = 0;
@@ -369,6 +373,9 @@ again:
369 nfs_refresh_inode(dentry->d_inode, &fattr); 373 nfs_refresh_inode(dentry->d_inode, &fattr);
370 dprintk("NFS reply setattr (post-create): %d\n", status); 374 dprintk("NFS reply setattr (post-create): %d\n", status);
371 } 375 }
376 if (status != 0)
377 goto out;
378 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
372out: 379out:
373 dprintk("NFS reply create: %d\n", status); 380 dprintk("NFS reply create: %d\n", status);
374 return status; 381 return status;
@@ -538,15 +545,24 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
538 .fh = &fhandle, 545 .fh = &fhandle,
539 .fattr = &fattr 546 .fattr = &fattr
540 }; 547 };
541 int status; 548 int mode = sattr->ia_mode;
549 int status;
542 550
543 dprintk("NFS call mkdir %s\n", dentry->d_name.name); 551 dprintk("NFS call mkdir %s\n", dentry->d_name.name);
544 dir_attr.valid = 0; 552 dir_attr.valid = 0;
545 fattr.valid = 0; 553 fattr.valid = 0;
554
555 sattr->ia_mode &= ~current->fs->umask;
556
546 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0); 557 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
547 nfs_refresh_inode(dir, &dir_attr); 558 nfs_refresh_inode(dir, &dir_attr);
548 if (status == 0) 559 if (status != 0)
549 status = nfs_instantiate(dentry, &fhandle, &fattr); 560 goto out;
561 status = nfs_instantiate(dentry, &fhandle, &fattr);
562 if (status != 0)
563 goto out;
564 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
565out:
550 dprintk("NFS reply mkdir: %d\n", status); 566 dprintk("NFS reply mkdir: %d\n", status);
551 return status; 567 return status;
552} 568}
@@ -641,6 +657,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
641 .fh = &fh, 657 .fh = &fh,
642 .fattr = &fattr 658 .fattr = &fattr
643 }; 659 };
660 mode_t mode = sattr->ia_mode;
644 int status; 661 int status;
645 662
646 switch (sattr->ia_mode & S_IFMT) { 663 switch (sattr->ia_mode & S_IFMT) {
@@ -653,12 +670,20 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
653 670
654 dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, 671 dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name,
655 MAJOR(rdev), MINOR(rdev)); 672 MAJOR(rdev), MINOR(rdev));
673
674 sattr->ia_mode &= ~current->fs->umask;
675
656 dir_attr.valid = 0; 676 dir_attr.valid = 0;
657 fattr.valid = 0; 677 fattr.valid = 0;
658 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0); 678 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
659 nfs_refresh_inode(dir, &dir_attr); 679 nfs_refresh_inode(dir, &dir_attr);
660 if (status == 0) 680 if (status != 0)
661 status = nfs_instantiate(dentry, &fh, &fattr); 681 goto out;
682 status = nfs_instantiate(dentry, &fh, &fattr);
683 if (status != 0)
684 goto out;
685 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
686out:
662 dprintk("NFS reply mknod: %d\n", status); 687 dprintk("NFS reply mknod: %d\n", status);
663 return status; 688 return status;
664} 689}
@@ -825,7 +850,8 @@ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
825struct nfs_rpc_ops nfs_v3_clientops = { 850struct nfs_rpc_ops nfs_v3_clientops = {
826 .version = 3, /* protocol version */ 851 .version = 3, /* protocol version */
827 .dentry_ops = &nfs_dentry_operations, 852 .dentry_ops = &nfs_dentry_operations,
828 .dir_inode_ops = &nfs_dir_inode_operations, 853 .dir_inode_ops = &nfs3_dir_inode_operations,
854 .file_inode_ops = &nfs3_file_inode_operations,
829 .getroot = nfs3_proc_get_root, 855 .getroot = nfs3_proc_get_root,
830 .getattr = nfs3_proc_getattr, 856 .getattr = nfs3_proc_getattr,
831 .setattr = nfs3_proc_setattr, 857 .setattr = nfs3_proc_setattr,
@@ -856,4 +882,5 @@ struct nfs_rpc_ops nfs_v3_clientops = {
856 .file_open = nfs_open, 882 .file_open = nfs_open,
857 .file_release = nfs_release, 883 .file_release = nfs_release,
858 .lock = nfs3_proc_lock, 884 .lock = nfs3_proc_lock,
885 .clear_acl_cache = nfs3_forget_cached_acls,
859}; 886};
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index a3593d47e5ab..db4a904810a4 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -21,6 +21,7 @@
21#include <linux/nfs.h> 21#include <linux/nfs.h>
22#include <linux/nfs3.h> 22#include <linux/nfs3.h>
23#include <linux/nfs_fs.h> 23#include <linux/nfs_fs.h>
24#include <linux/nfsacl.h>
24 25
25#define NFSDBG_FACILITY NFSDBG_XDR 26#define NFSDBG_FACILITY NFSDBG_XDR
26 27
@@ -79,6 +80,11 @@ extern int nfs_stat_to_errno(int);
79#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6) 80#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
80#define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) 81#define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
81 82
83#define ACL3_getaclargs_sz (NFS3_fh_sz+1)
84#define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3))
85#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3))
86#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
87
82/* 88/*
83 * Map file type to S_IFMT bits 89 * Map file type to S_IFMT bits
84 */ 90 */
@@ -627,6 +633,74 @@ nfs3_xdr_commitargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
627 return 0; 633 return 0;
628} 634}
629 635
636#ifdef CONFIG_NFS_V3_ACL
637/*
638 * Encode GETACL arguments
639 */
640static int
641nfs3_xdr_getaclargs(struct rpc_rqst *req, u32 *p,
642 struct nfs3_getaclargs *args)
643{
644 struct rpc_auth *auth = req->rq_task->tk_auth;
645 unsigned int replen;
646
647 p = xdr_encode_fhandle(p, args->fh);
648 *p++ = htonl(args->mask);
649 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
650
651 if (args->mask & (NFS_ACL | NFS_DFACL)) {
652 /* Inline the page array */
653 replen = (RPC_REPHDRSIZE + auth->au_rslack +
654 ACL3_getaclres_sz) << 2;
655 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
656 NFSACL_MAXPAGES << PAGE_SHIFT);
657 }
658 return 0;
659}
660
661/*
662 * Encode SETACL arguments
663 */
664static int
665nfs3_xdr_setaclargs(struct rpc_rqst *req, u32 *p,
666 struct nfs3_setaclargs *args)
667{
668 struct xdr_buf *buf = &req->rq_snd_buf;
669 unsigned int base, len_in_head, len = nfsacl_size(
670 (args->mask & NFS_ACL) ? args->acl_access : NULL,
671 (args->mask & NFS_DFACL) ? args->acl_default : NULL);
672 int count, err;
673
674 p = xdr_encode_fhandle(p, NFS_FH(args->inode));
675 *p++ = htonl(args->mask);
676 base = (char *)p - (char *)buf->head->iov_base;
677 /* put as much of the acls into head as possible. */
678 len_in_head = min_t(unsigned int, buf->head->iov_len - base, len);
679 len -= len_in_head;
680 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2));
681
682 for (count = 0; (count << PAGE_SHIFT) < len; count++) {
683 args->pages[count] = alloc_page(GFP_KERNEL);
684 if (!args->pages[count]) {
685 while (count)
686 __free_page(args->pages[--count]);
687 return -ENOMEM;
688 }
689 }
690 xdr_encode_pages(buf, args->pages, 0, len);
691
692 err = nfsacl_encode(buf, base, args->inode,
693 (args->mask & NFS_ACL) ?
694 args->acl_access : NULL, 1, 0);
695 if (err > 0)
696 err = nfsacl_encode(buf, base + err, args->inode,
697 (args->mask & NFS_DFACL) ?
698 args->acl_default : NULL, 1,
699 NFS_ACL_DEFAULT);
700 return (err > 0) ? 0 : err;
701}
702#endif /* CONFIG_NFS_V3_ACL */
703
630/* 704/*
631 * NFS XDR decode functions 705 * NFS XDR decode functions
632 */ 706 */
@@ -978,6 +1052,54 @@ nfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
978 return 0; 1052 return 0;
979} 1053}
980 1054
1055#ifdef CONFIG_NFS_V3_ACL
1056/*
1057 * Decode GETACL reply
1058 */
1059static int
1060nfs3_xdr_getaclres(struct rpc_rqst *req, u32 *p,
1061 struct nfs3_getaclres *res)
1062{
1063 struct xdr_buf *buf = &req->rq_rcv_buf;
1064 int status = ntohl(*p++);
1065 struct posix_acl **acl;
1066 unsigned int *aclcnt;
1067 int err, base;
1068
1069 if (status != 0)
1070 return -nfs_stat_to_errno(status);
1071 p = xdr_decode_post_op_attr(p, res->fattr);
1072 res->mask = ntohl(*p++);
1073 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1074 return -EINVAL;
1075 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1076
1077 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1078 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1079 err = nfsacl_decode(buf, base, aclcnt, acl);
1080
1081 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1082 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1083 if (err > 0)
1084 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1085 return (err > 0) ? 0 : err;
1086}
1087
1088/*
1089 * Decode setacl reply.
1090 */
1091static int
1092nfs3_xdr_setaclres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
1093{
1094 int status = ntohl(*p++);
1095
1096 if (status)
1097 return -nfs_stat_to_errno(status);
1098 xdr_decode_post_op_attr(p, fattr);
1099 return 0;
1100}
1101#endif /* CONFIG_NFS_V3_ACL */
1102
981#ifndef MAX 1103#ifndef MAX
982# define MAX(a, b) (((a) > (b))? (a) : (b)) 1104# define MAX(a, b) (((a) > (b))? (a) : (b))
983#endif 1105#endif
@@ -1021,3 +1143,28 @@ struct rpc_version nfs_version3 = {
1021 .procs = nfs3_procedures 1143 .procs = nfs3_procedures
1022}; 1144};
1023 1145
1146#ifdef CONFIG_NFS_V3_ACL
1147static struct rpc_procinfo nfs3_acl_procedures[] = {
1148 [ACLPROC3_GETACL] = {
1149 .p_proc = ACLPROC3_GETACL,
1150 .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
1151 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
1152 .p_bufsiz = MAX(ACL3_getaclargs_sz, ACL3_getaclres_sz) << 2,
1153 .p_timer = 1,
1154 },
1155 [ACLPROC3_SETACL] = {
1156 .p_proc = ACLPROC3_SETACL,
1157 .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
1158 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
1159 .p_bufsiz = MAX(ACL3_setaclargs_sz, ACL3_setaclres_sz) << 2,
1160 .p_timer = 0,
1161 },
1162};
1163
1164struct rpc_version nfsacl_version3 = {
1165 .number = 3,
1166 .nrprocs = sizeof(nfs3_acl_procedures)/
1167 sizeof(nfs3_acl_procedures[0]),
1168 .procs = nfs3_acl_procedures,
1169};
1170#endif /* CONFIG_NFS_V3_ACL */
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
new file mode 100644
index 000000000000..ec1a22d7b876
--- /dev/null
+++ b/fs/nfs/nfs4_fs.h
@@ -0,0 +1,253 @@
1/*
2 * linux/fs/nfs/nfs4_fs.h
3 *
4 * Copyright (C) 2005 Trond Myklebust
5 *
6 * NFSv4-specific filesystem definitions and declarations
7 */
8
9#ifndef __LINUX_FS_NFS_NFS4_FS_H
10#define __LINUX_FS_NFS_NFS4_FS_H
11
12#ifdef CONFIG_NFS_V4
13
14struct idmap;
15
16/*
17 * In a seqid-mutating op, this macro controls which error return
18 * values trigger incrementation of the seqid.
19 *
20 * from rfc 3010:
21 * The client MUST monotonically increment the sequence number for the
22 * CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
23 * operations. This is true even in the event that the previous
24 * operation that used the sequence number received an error. The only
25 * exception to this rule is if the previous operation received one of
26 * the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
27 * NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
28 * NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
29 *
30 */
31#define seqid_mutating_err(err) \
32(((err) != NFSERR_STALE_CLIENTID) && \
33 ((err) != NFSERR_STALE_STATEID) && \
34 ((err) != NFSERR_BAD_STATEID) && \
35 ((err) != NFSERR_BAD_SEQID) && \
36 ((err) != NFSERR_BAD_XDR) && \
37 ((err) != NFSERR_RESOURCE) && \
38 ((err) != NFSERR_NOFILEHANDLE))
39
40enum nfs4_client_state {
41 NFS4CLNT_OK = 0,
42};
43
44/*
45 * The nfs4_client identifies our client state to the server.
46 */
47struct nfs4_client {
48 struct list_head cl_servers; /* Global list of servers */
49 struct in_addr cl_addr; /* Server identifier */
50 u64 cl_clientid; /* constant */
51 nfs4_verifier cl_confirm;
52 unsigned long cl_state;
53
54 u32 cl_lockowner_id;
55
56 /*
57 * The following rwsem ensures exclusive access to the server
58 * while we recover the state following a lease expiration.
59 */
60 struct rw_semaphore cl_sem;
61
62 struct list_head cl_delegations;
63 struct list_head cl_state_owners;
64 struct list_head cl_unused;
65 int cl_nunused;
66 spinlock_t cl_lock;
67 atomic_t cl_count;
68
69 struct rpc_clnt * cl_rpcclient;
70 struct rpc_cred * cl_cred;
71
72 struct list_head cl_superblocks; /* List of nfs_server structs */
73
74 unsigned long cl_lease_time;
75 unsigned long cl_last_renewal;
76 struct work_struct cl_renewd;
77 struct work_struct cl_recoverd;
78
79 wait_queue_head_t cl_waitq;
80 struct rpc_wait_queue cl_rpcwaitq;
81
82 /* used for the setclientid verifier */
83 struct timespec cl_boot_time;
84
85 /* idmapper */
86 struct idmap * cl_idmap;
87
88 /* Our own IP address, as a null-terminated string.
89 * This is used to generate the clientid, and the callback address.
90 */
91 char cl_ipaddr[16];
92 unsigned char cl_id_uniquifier;
93};
94
95/*
96 * NFS4 state_owners and lock_owners are simply labels for ordered
97 * sequences of RPC calls. Their sole purpose is to provide once-only
98 * semantics by allowing the server to identify replayed requests.
99 *
100 * The ->so_sema is held during all state_owner seqid-mutating operations:
101 * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
102 * so_seqid.
103 */
104struct nfs4_state_owner {
105 struct list_head so_list; /* per-clientid list of state_owners */
106 struct nfs4_client *so_client;
107 u32 so_id; /* 32-bit identifier, unique */
108 struct semaphore so_sema;
109 u32 so_seqid; /* protected by so_sema */
110 atomic_t so_count;
111
112 struct rpc_cred *so_cred; /* Associated cred */
113 struct list_head so_states;
114 struct list_head so_delegations;
115};
116
117/*
118 * struct nfs4_state maintains the client-side state for a given
119 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
120 *
121 * OPEN:
122 * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
123 * we need to know how many files are open for reading or writing on a
124 * given inode. This information too is stored here.
125 *
126 * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
127 */
128
129struct nfs4_lock_state {
130 struct list_head ls_locks; /* Other lock stateids */
131 struct nfs4_state * ls_state; /* Pointer to open state */
132 fl_owner_t ls_owner; /* POSIX lock owner */
133#define NFS_LOCK_INITIALIZED 1
134 int ls_flags;
135 u32 ls_seqid;
136 u32 ls_id;
137 nfs4_stateid ls_stateid;
138 atomic_t ls_count;
139};
140
141/* bits for nfs4_state->flags */
142enum {
143 LK_STATE_IN_USE,
144 NFS_DELEGATED_STATE,
145};
146
147struct nfs4_state {
148 struct list_head open_states; /* List of states for the same state_owner */
149 struct list_head inode_states; /* List of states for the same inode */
150 struct list_head lock_states; /* List of subservient lock stateids */
151
152 struct nfs4_state_owner *owner; /* Pointer to the open owner */
153 struct inode *inode; /* Pointer to the inode */
154
155 unsigned long flags; /* Do we hold any locks? */
156 struct semaphore lock_sema; /* Serializes file locking operations */
157 spinlock_t state_lock; /* Protects the lock_states list */
158
159 nfs4_stateid stateid;
160
161 unsigned int nreaders;
162 unsigned int nwriters;
163 int state; /* State on the server (R,W, or RW) */
164 atomic_t count;
165};
166
167
168struct nfs4_exception {
169 long timeout;
170 int retry;
171};
172
173struct nfs4_state_recovery_ops {
174 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
175 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
176};
177
178extern struct dentry_operations nfs4_dentry_operations;
179extern struct inode_operations nfs4_dir_inode_operations;
180
181/* inode.c */
182extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
183extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int);
184extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
185
186
187/* nfs4proc.c */
188extern int nfs4_map_errors(int err);
189extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
190extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
191extern int nfs4_proc_async_renew(struct nfs4_client *);
192extern int nfs4_proc_renew(struct nfs4_client *);
193extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
194extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
195extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
196
197extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
198extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
199
200extern const u32 nfs4_fattr_bitmap[2];
201extern const u32 nfs4_statfs_bitmap[2];
202extern const u32 nfs4_pathconf_bitmap[2];
203extern const u32 nfs4_fsinfo_bitmap[2];
204
205/* nfs4renewd.c */
206extern void nfs4_schedule_state_renewal(struct nfs4_client *);
207extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
208extern void nfs4_kill_renewd(struct nfs4_client *);
209extern void nfs4_renew_state(void *);
210
211/* nfs4state.c */
212extern void init_nfsv4_state(struct nfs_server *);
213extern void destroy_nfsv4_state(struct nfs_server *);
214extern struct nfs4_client *nfs4_get_client(struct in_addr *);
215extern void nfs4_put_client(struct nfs4_client *clp);
216extern int nfs4_init_client(struct nfs4_client *clp);
217extern struct nfs4_client *nfs4_find_client(struct in_addr *);
218extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
219
220extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
221extern void nfs4_put_state_owner(struct nfs4_state_owner *);
222extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
223extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
224extern void nfs4_put_open_state(struct nfs4_state *);
225extern void nfs4_close_state(struct nfs4_state *, mode_t);
226extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
227extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
228extern void nfs4_schedule_state_recovery(struct nfs4_client *);
229extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
230extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
231extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
232
233extern const nfs4_stateid zero_stateid;
234
235/* nfs4xdr.c */
236extern uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus);
237extern struct rpc_procinfo nfs4_procedures[];
238
239struct nfs4_mount_data;
240
241/* callback_xdr.c */
242extern struct svc_version nfs4_callback_version1;
243
244#else
245
246#define init_nfsv4_state(server) do { } while (0)
247#define destroy_nfsv4_state(server) do { } while (0)
248#define nfs4_put_state_owner(inode, owner) do { } while (0)
249#define nfs4_put_open_state(state) do { } while (0)
250#define nfs4_close_state(a, b) do { } while (0)
251
252#endif /* CONFIG_NFS_V4 */
253#endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1d5cb3e80c3e..1b76f80aedb9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -48,6 +48,7 @@
48#include <linux/smp_lock.h> 48#include <linux/smp_lock.h>
49#include <linux/namei.h> 49#include <linux/namei.h>
50 50
51#include "nfs4_fs.h"
51#include "delegation.h" 52#include "delegation.h"
52 53
53#define NFSDBG_FACILITY NFSDBG_PROC 54#define NFSDBG_FACILITY NFSDBG_PROC
@@ -62,8 +63,6 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
62extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); 63extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
63extern struct rpc_procinfo nfs4_procedures[]; 64extern struct rpc_procinfo nfs4_procedures[];
64 65
65extern nfs4_stateid zero_stateid;
66
67/* Prevent leaks of NFSv4 errors into userland */ 66/* Prevent leaks of NFSv4 errors into userland */
68int nfs4_map_errors(int err) 67int nfs4_map_errors(int err)
69{ 68{
@@ -104,7 +103,7 @@ const u32 nfs4_statfs_bitmap[2] = {
104 | FATTR4_WORD1_SPACE_TOTAL 103 | FATTR4_WORD1_SPACE_TOTAL
105}; 104};
106 105
107u32 nfs4_pathconf_bitmap[2] = { 106const u32 nfs4_pathconf_bitmap[2] = {
108 FATTR4_WORD0_MAXLINK 107 FATTR4_WORD0_MAXLINK
109 | FATTR4_WORD0_MAXNAME, 108 | FATTR4_WORD0_MAXNAME,
110 0 109 0
@@ -124,7 +123,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
124 123
125 BUG_ON(readdir->count < 80); 124 BUG_ON(readdir->count < 80);
126 if (cookie > 2) { 125 if (cookie > 2) {
127 readdir->cookie = (cookie > 2) ? cookie : 0; 126 readdir->cookie = cookie;
128 memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier)); 127 memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier));
129 return; 128 return;
130 } 129 }
@@ -270,14 +269,9 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
270 int err; 269 int err;
271 do { 270 do {
272 err = _nfs4_open_reclaim(sp, state); 271 err = _nfs4_open_reclaim(sp, state);
273 switch (err) { 272 if (err != -NFS4ERR_DELAY)
274 case 0: 273 break;
275 case -NFS4ERR_STALE_CLIENTID: 274 nfs4_handle_exception(server, err, &exception);
276 case -NFS4ERR_STALE_STATEID:
277 case -NFS4ERR_EXPIRED:
278 return err;
279 }
280 err = nfs4_handle_exception(server, err, &exception);
281 } while (exception.retry); 275 } while (exception.retry);
282 return err; 276 return err;
283} 277}
@@ -509,6 +503,20 @@ out_stale:
509 goto out_nodeleg; 503 goto out_nodeleg;
510} 504}
511 505
506static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
507{
508 struct nfs_server *server = NFS_SERVER(dentry->d_inode);
509 struct nfs4_exception exception = { };
510 int err;
511
512 do {
513 err = _nfs4_open_expired(sp, state, dentry);
514 if (err == -NFS4ERR_DELAY)
515 nfs4_handle_exception(server, err, &exception);
516 } while (exception.retry);
517 return err;
518}
519
512static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) 520static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
513{ 521{
514 struct nfs_inode *nfsi = NFS_I(state->inode); 522 struct nfs_inode *nfsi = NFS_I(state->inode);
@@ -521,7 +529,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
521 continue; 529 continue;
522 get_nfs_open_context(ctx); 530 get_nfs_open_context(ctx);
523 spin_unlock(&state->inode->i_lock); 531 spin_unlock(&state->inode->i_lock);
524 status = _nfs4_open_expired(sp, state, ctx->dentry); 532 status = nfs4_do_open_expired(sp, state, ctx->dentry);
525 put_nfs_open_context(ctx); 533 put_nfs_open_context(ctx);
526 return status; 534 return status;
527 } 535 }
@@ -748,11 +756,10 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
748 756
749 fattr->valid = 0; 757 fattr->valid = 0;
750 758
751 if (state != NULL) 759 if (state != NULL) {
752 msg.rpc_cred = state->owner->so_cred; 760 msg.rpc_cred = state->owner->so_cred;
753 if (sattr->ia_valid & ATTR_SIZE) 761 nfs4_copy_stateid(&arg.stateid, state, current->files);
754 nfs4_copy_stateid(&arg.stateid, state, NULL); 762 } else
755 else
756 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); 763 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
757 764
758 return rpc_call_sync(server->client, &msg, 0); 765 return rpc_call_sync(server->client, &msg, 0);
@@ -1116,47 +1123,31 @@ static int
1116nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, 1123nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
1117 struct iattr *sattr) 1124 struct iattr *sattr)
1118{ 1125{
1119 struct inode * inode = dentry->d_inode; 1126 struct rpc_cred *cred;
1120 int size_change = sattr->ia_valid & ATTR_SIZE; 1127 struct inode *inode = dentry->d_inode;
1121 struct nfs4_state *state = NULL; 1128 struct nfs4_state *state;
1122 int need_iput = 0;
1123 int status; 1129 int status;
1124 1130
1125 fattr->valid = 0; 1131 fattr->valid = 0;
1126 1132
1127 if (size_change) { 1133 cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
1128 struct rpc_cred *cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0); 1134 if (IS_ERR(cred))
1129 if (IS_ERR(cred)) 1135 return PTR_ERR(cred);
1130 return PTR_ERR(cred); 1136 /* Search for an existing WRITE delegation first */
1137 state = nfs4_open_delegated(inode, FMODE_WRITE, cred);
1138 if (!IS_ERR(state)) {
1139 /* NB: nfs4_open_delegated() bumps the inode->i_count */
1140 iput(inode);
1141 } else {
1142 /* Search for an existing open(O_WRITE) stateid */
1131 state = nfs4_find_state(inode, cred, FMODE_WRITE); 1143 state = nfs4_find_state(inode, cred, FMODE_WRITE);
1132 if (state == NULL) {
1133 state = nfs4_open_delegated(dentry->d_inode,
1134 FMODE_WRITE, cred);
1135 if (IS_ERR(state))
1136 state = nfs4_do_open(dentry->d_parent->d_inode,
1137 dentry, FMODE_WRITE,
1138 NULL, cred);
1139 need_iput = 1;
1140 }
1141 put_rpccred(cred);
1142 if (IS_ERR(state))
1143 return PTR_ERR(state);
1144
1145 if (state->inode != inode) {
1146 printk(KERN_WARNING "nfs: raced in setattr (%p != %p), returning -EIO\n", inode, state->inode);
1147 status = -EIO;
1148 goto out;
1149 }
1150 } 1144 }
1145
1151 status = nfs4_do_setattr(NFS_SERVER(inode), fattr, 1146 status = nfs4_do_setattr(NFS_SERVER(inode), fattr,
1152 NFS_FH(inode), sattr, state); 1147 NFS_FH(inode), sattr, state);
1153out: 1148 if (state != NULL)
1154 if (state) {
1155 inode = state->inode;
1156 nfs4_close_state(state, FMODE_WRITE); 1149 nfs4_close_state(state, FMODE_WRITE);
1157 if (need_iput) 1150 put_rpccred(cred);
1158 iput(inode);
1159 }
1160 return status; 1151 return status;
1161} 1152}
1162 1153
@@ -1731,6 +1722,10 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
1731 }; 1722 };
1732 int status; 1723 int status;
1733 1724
1725 dprintk("%s: dentry = %s/%s, cookie = %Lu\n", __FUNCTION__,
1726 dentry->d_parent->d_name.name,
1727 dentry->d_name.name,
1728 (unsigned long long)cookie);
1734 lock_kernel(); 1729 lock_kernel();
1735 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 1730 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
1736 res.pgbase = args.pgbase; 1731 res.pgbase = args.pgbase;
@@ -1738,6 +1733,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
1738 if (status == 0) 1733 if (status == 0)
1739 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 1734 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
1740 unlock_kernel(); 1735 unlock_kernel();
1736 dprintk("%s: returns %d\n", __FUNCTION__, status);
1741 return status; 1737 return status;
1742} 1738}
1743 1739
@@ -2163,6 +2159,193 @@ nfs4_proc_file_release(struct inode *inode, struct file *filp)
2163 return 0; 2159 return 0;
2164} 2160}
2165 2161
2162static inline int nfs4_server_supports_acls(struct nfs_server *server)
2163{
2164 return (server->caps & NFS_CAP_ACLS)
2165 && (server->acl_bitmask & ACL4_SUPPORT_ALLOW_ACL)
2166 && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL);
2167}
2168
2169/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that
2170 * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on
2171 * the stack.
2172 */
2173#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
2174
2175static void buf_to_pages(const void *buf, size_t buflen,
2176 struct page **pages, unsigned int *pgbase)
2177{
2178 const void *p = buf;
2179
2180 *pgbase = offset_in_page(buf);
2181 p -= *pgbase;
2182 while (p < buf + buflen) {
2183 *(pages++) = virt_to_page(p);
2184 p += PAGE_CACHE_SIZE;
2185 }
2186}
2187
2188struct nfs4_cached_acl {
2189 int cached;
2190 size_t len;
2191 char data[0];
2192};
2193
2194static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl)
2195{
2196 struct nfs_inode *nfsi = NFS_I(inode);
2197
2198 spin_lock(&inode->i_lock);
2199 kfree(nfsi->nfs4_acl);
2200 nfsi->nfs4_acl = acl;
2201 spin_unlock(&inode->i_lock);
2202}
2203
2204static void nfs4_zap_acl_attr(struct inode *inode)
2205{
2206 nfs4_set_cached_acl(inode, NULL);
2207}
2208
2209static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
2210{
2211 struct nfs_inode *nfsi = NFS_I(inode);
2212 struct nfs4_cached_acl *acl;
2213 int ret = -ENOENT;
2214
2215 spin_lock(&inode->i_lock);
2216 acl = nfsi->nfs4_acl;
2217 if (acl == NULL)
2218 goto out;
2219 if (buf == NULL) /* user is just asking for length */
2220 goto out_len;
2221 if (acl->cached == 0)
2222 goto out;
2223 ret = -ERANGE; /* see getxattr(2) man page */
2224 if (acl->len > buflen)
2225 goto out;
2226 memcpy(buf, acl->data, acl->len);
2227out_len:
2228 ret = acl->len;
2229out:
2230 spin_unlock(&inode->i_lock);
2231 return ret;
2232}
2233
2234static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len)
2235{
2236 struct nfs4_cached_acl *acl;
2237
2238 if (buf && acl_len <= PAGE_SIZE) {
2239 acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
2240 if (acl == NULL)
2241 goto out;
2242 acl->cached = 1;
2243 memcpy(acl->data, buf, acl_len);
2244 } else {
2245 acl = kmalloc(sizeof(*acl), GFP_KERNEL);
2246 if (acl == NULL)
2247 goto out;
2248 acl->cached = 0;
2249 }
2250 acl->len = acl_len;
2251out:
2252 nfs4_set_cached_acl(inode, acl);
2253}
2254
2255static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
2256{
2257 struct page *pages[NFS4ACL_MAXPAGES];
2258 struct nfs_getaclargs args = {
2259 .fh = NFS_FH(inode),
2260 .acl_pages = pages,
2261 .acl_len = buflen,
2262 };
2263 size_t resp_len = buflen;
2264 void *resp_buf;
2265 struct rpc_message msg = {
2266 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
2267 .rpc_argp = &args,
2268 .rpc_resp = &resp_len,
2269 };
2270 struct page *localpage = NULL;
2271 int ret;
2272
2273 if (buflen < PAGE_SIZE) {
2274 /* As long as we're doing a round trip to the server anyway,
2275 * let's be prepared for a page of acl data. */
2276 localpage = alloc_page(GFP_KERNEL);
2277 resp_buf = page_address(localpage);
2278 if (localpage == NULL)
2279 return -ENOMEM;
2280 args.acl_pages[0] = localpage;
2281 args.acl_pgbase = 0;
2282 args.acl_len = PAGE_SIZE;
2283 } else {
2284 resp_buf = buf;
2285 buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
2286 }
2287 ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
2288 if (ret)
2289 goto out_free;
2290 if (resp_len > args.acl_len)
2291 nfs4_write_cached_acl(inode, NULL, resp_len);
2292 else
2293 nfs4_write_cached_acl(inode, resp_buf, resp_len);
2294 if (buf) {
2295 ret = -ERANGE;
2296 if (resp_len > buflen)
2297 goto out_free;
2298 if (localpage)
2299 memcpy(buf, resp_buf, resp_len);
2300 }
2301 ret = resp_len;
2302out_free:
2303 if (localpage)
2304 __free_page(localpage);
2305 return ret;
2306}
2307
2308static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
2309{
2310 struct nfs_server *server = NFS_SERVER(inode);
2311 int ret;
2312
2313 if (!nfs4_server_supports_acls(server))
2314 return -EOPNOTSUPP;
2315 ret = nfs_revalidate_inode(server, inode);
2316 if (ret < 0)
2317 return ret;
2318 ret = nfs4_read_cached_acl(inode, buf, buflen);
2319 if (ret != -ENOENT)
2320 return ret;
2321 return nfs4_get_acl_uncached(inode, buf, buflen);
2322}
2323
2324static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
2325{
2326 struct nfs_server *server = NFS_SERVER(inode);
2327 struct page *pages[NFS4ACL_MAXPAGES];
2328 struct nfs_setaclargs arg = {
2329 .fh = NFS_FH(inode),
2330 .acl_pages = pages,
2331 .acl_len = buflen,
2332 };
2333 struct rpc_message msg = {
2334 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
2335 .rpc_argp = &arg,
2336 .rpc_resp = NULL,
2337 };
2338 int ret;
2339
2340 if (!nfs4_server_supports_acls(server))
2341 return -EOPNOTSUPP;
2342 buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
2343 ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
2344 if (ret == 0)
2345 nfs4_write_cached_acl(inode, buf, buflen);
2346 return ret;
2347}
2348
2166static int 2349static int
2167nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server) 2350nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server)
2168{ 2351{
@@ -2448,14 +2631,11 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
2448 down_read(&clp->cl_sem); 2631 down_read(&clp->cl_sem);
2449 nlo.clientid = clp->cl_clientid; 2632 nlo.clientid = clp->cl_clientid;
2450 down(&state->lock_sema); 2633 down(&state->lock_sema);
2451 lsp = nfs4_find_lock_state(state, request->fl_owner); 2634 status = nfs4_set_lock_state(state, request);
2452 if (lsp) 2635 if (status != 0)
2453 nlo.id = lsp->ls_id; 2636 goto out;
2454 else { 2637 lsp = request->fl_u.nfs4_fl.owner;
2455 spin_lock(&clp->cl_lock); 2638 nlo.id = lsp->ls_id;
2456 nlo.id = nfs4_alloc_lockowner_id(clp);
2457 spin_unlock(&clp->cl_lock);
2458 }
2459 arg.u.lockt = &nlo; 2639 arg.u.lockt = &nlo;
2460 status = rpc_call_sync(server->client, &msg, 0); 2640 status = rpc_call_sync(server->client, &msg, 0);
2461 if (!status) { 2641 if (!status) {
@@ -2476,8 +2656,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
2476 request->fl_pid = 0; 2656 request->fl_pid = 0;
2477 status = 0; 2657 status = 0;
2478 } 2658 }
2479 if (lsp) 2659out:
2480 nfs4_put_lock_state(lsp);
2481 up(&state->lock_sema); 2660 up(&state->lock_sema);
2482 up_read(&clp->cl_sem); 2661 up_read(&clp->cl_sem);
2483 return status; 2662 return status;
@@ -2537,28 +2716,26 @@ static int _nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock
2537 }; 2716 };
2538 struct nfs4_lock_state *lsp; 2717 struct nfs4_lock_state *lsp;
2539 struct nfs_locku_opargs luargs; 2718 struct nfs_locku_opargs luargs;
2540 int status = 0; 2719 int status;
2541 2720
2542 down_read(&clp->cl_sem); 2721 down_read(&clp->cl_sem);
2543 down(&state->lock_sema); 2722 down(&state->lock_sema);
2544 lsp = nfs4_find_lock_state(state, request->fl_owner); 2723 status = nfs4_set_lock_state(state, request);
2545 if (!lsp) 2724 if (status != 0)
2546 goto out; 2725 goto out;
2726 lsp = request->fl_u.nfs4_fl.owner;
2547 /* We might have lost the locks! */ 2727 /* We might have lost the locks! */
2548 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) { 2728 if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
2549 luargs.seqid = lsp->ls_seqid; 2729 goto out;
2550 memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid)); 2730 luargs.seqid = lsp->ls_seqid;
2551 arg.u.locku = &luargs; 2731 memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
2552 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 2732 arg.u.locku = &luargs;
2553 nfs4_increment_lock_seqid(status, lsp); 2733 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
2554 } 2734 nfs4_increment_lock_seqid(status, lsp);
2555 2735
2556 if (status == 0) { 2736 if (status == 0)
2557 memcpy(&lsp->ls_stateid, &res.u.stateid, 2737 memcpy(&lsp->ls_stateid, &res.u.stateid,
2558 sizeof(lsp->ls_stateid)); 2738 sizeof(lsp->ls_stateid));
2559 nfs4_notify_unlck(state, request, lsp);
2560 }
2561 nfs4_put_lock_state(lsp);
2562out: 2739out:
2563 up(&state->lock_sema); 2740 up(&state->lock_sema);
2564 if (status == 0) 2741 if (status == 0)
@@ -2584,7 +2761,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
2584{ 2761{
2585 struct inode *inode = state->inode; 2762 struct inode *inode = state->inode;
2586 struct nfs_server *server = NFS_SERVER(inode); 2763 struct nfs_server *server = NFS_SERVER(inode);
2587 struct nfs4_lock_state *lsp; 2764 struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
2588 struct nfs_lockargs arg = { 2765 struct nfs_lockargs arg = {
2589 .fh = NFS_FH(inode), 2766 .fh = NFS_FH(inode),
2590 .type = nfs4_lck_type(cmd, request), 2767 .type = nfs4_lck_type(cmd, request),
@@ -2606,9 +2783,6 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
2606 }; 2783 };
2607 int status; 2784 int status;
2608 2785
2609 lsp = nfs4_get_lock_state(state, request->fl_owner);
2610 if (lsp == NULL)
2611 return -ENOMEM;
2612 if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) { 2786 if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) {
2613 struct nfs4_state_owner *owner = state->owner; 2787 struct nfs4_state_owner *owner = state->owner;
2614 struct nfs_open_to_lock otl = { 2788 struct nfs_open_to_lock otl = {
@@ -2630,38 +2804,57 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *r
2630 * seqid mutating errors */ 2804 * seqid mutating errors */
2631 nfs4_increment_seqid(status, owner); 2805 nfs4_increment_seqid(status, owner);
2632 up(&owner->so_sema); 2806 up(&owner->so_sema);
2807 if (status == 0) {
2808 lsp->ls_flags |= NFS_LOCK_INITIALIZED;
2809 lsp->ls_seqid++;
2810 }
2633 } else { 2811 } else {
2634 struct nfs_exist_lock el = { 2812 struct nfs_exist_lock el = {
2635 .seqid = lsp->ls_seqid, 2813 .seqid = lsp->ls_seqid,
2636 }; 2814 };
2637 memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid)); 2815 memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
2638 largs.u.exist_lock = &el; 2816 largs.u.exist_lock = &el;
2639 largs.new_lock_owner = 0;
2640 arg.u.lock = &largs; 2817 arg.u.lock = &largs;
2641 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); 2818 status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
2819 /* increment seqid on success, and * seqid mutating errors*/
2820 nfs4_increment_lock_seqid(status, lsp);
2642 } 2821 }
2643 /* increment seqid on success, and * seqid mutating errors*/
2644 nfs4_increment_lock_seqid(status, lsp);
2645 /* save the returned stateid. */ 2822 /* save the returned stateid. */
2646 if (status == 0) { 2823 if (status == 0)
2647 memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid)); 2824 memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid));
2648 lsp->ls_flags |= NFS_LOCK_INITIALIZED; 2825 else if (status == -NFS4ERR_DENIED)
2649 if (!reclaim)
2650 nfs4_notify_setlk(state, request, lsp);
2651 } else if (status == -NFS4ERR_DENIED)
2652 status = -EAGAIN; 2826 status = -EAGAIN;
2653 nfs4_put_lock_state(lsp);
2654 return status; 2827 return status;
2655} 2828}
2656 2829
2657static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) 2830static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
2658{ 2831{
2659 return _nfs4_do_setlk(state, F_SETLK, request, 1); 2832 struct nfs_server *server = NFS_SERVER(state->inode);
2833 struct nfs4_exception exception = { };
2834 int err;
2835
2836 do {
2837 err = _nfs4_do_setlk(state, F_SETLK, request, 1);
2838 if (err != -NFS4ERR_DELAY)
2839 break;
2840 nfs4_handle_exception(server, err, &exception);
2841 } while (exception.retry);
2842 return err;
2660} 2843}
2661 2844
2662static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) 2845static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
2663{ 2846{
2664 return _nfs4_do_setlk(state, F_SETLK, request, 0); 2847 struct nfs_server *server = NFS_SERVER(state->inode);
2848 struct nfs4_exception exception = { };
2849 int err;
2850
2851 do {
2852 err = _nfs4_do_setlk(state, F_SETLK, request, 0);
2853 if (err != -NFS4ERR_DELAY)
2854 break;
2855 nfs4_handle_exception(server, err, &exception);
2856 } while (exception.retry);
2857 return err;
2665} 2858}
2666 2859
2667static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 2860static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
@@ -2671,7 +2864,9 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
2671 2864
2672 down_read(&clp->cl_sem); 2865 down_read(&clp->cl_sem);
2673 down(&state->lock_sema); 2866 down(&state->lock_sema);
2674 status = _nfs4_do_setlk(state, cmd, request, 0); 2867 status = nfs4_set_lock_state(state, request);
2868 if (status == 0)
2869 status = _nfs4_do_setlk(state, cmd, request, 0);
2675 up(&state->lock_sema); 2870 up(&state->lock_sema);
2676 if (status == 0) { 2871 if (status == 0) {
2677 /* Note: we always want to sleep here! */ 2872 /* Note: we always want to sleep here! */
@@ -2729,10 +2924,53 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
2729 if (signalled()) 2924 if (signalled())
2730 break; 2925 break;
2731 } while(status < 0); 2926 } while(status < 0);
2732
2733 return status; 2927 return status;
2734} 2928}
2735 2929
2930
2931#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
2932
2933int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
2934 size_t buflen, int flags)
2935{
2936 struct inode *inode = dentry->d_inode;
2937
2938 if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
2939 return -EOPNOTSUPP;
2940
2941 if (!S_ISREG(inode->i_mode) &&
2942 (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
2943 return -EPERM;
2944
2945 return nfs4_proc_set_acl(inode, buf, buflen);
2946}
2947
2948/* The getxattr man page suggests returning -ENODATA for unknown attributes,
2949 * and that's what we'll do for e.g. user attributes that haven't been set.
2950 * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported
2951 * attributes in kernel-managed attribute namespaces. */
2952ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
2953 size_t buflen)
2954{
2955 struct inode *inode = dentry->d_inode;
2956
2957 if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
2958 return -EOPNOTSUPP;
2959
2960 return nfs4_proc_get_acl(inode, buf, buflen);
2961}
2962
2963ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
2964{
2965 size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1;
2966
2967 if (buf && buflen < len)
2968 return -ERANGE;
2969 if (buf)
2970 memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
2971 return len;
2972}
2973
2736struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { 2974struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
2737 .recover_open = nfs4_open_reclaim, 2975 .recover_open = nfs4_open_reclaim,
2738 .recover_lock = nfs4_lock_reclaim, 2976 .recover_lock = nfs4_lock_reclaim,
@@ -2743,10 +2981,20 @@ struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops = {
2743 .recover_lock = nfs4_lock_expired, 2981 .recover_lock = nfs4_lock_expired,
2744}; 2982};
2745 2983
2984static struct inode_operations nfs4_file_inode_operations = {
2985 .permission = nfs_permission,
2986 .getattr = nfs_getattr,
2987 .setattr = nfs_setattr,
2988 .getxattr = nfs4_getxattr,
2989 .setxattr = nfs4_setxattr,
2990 .listxattr = nfs4_listxattr,
2991};
2992
2746struct nfs_rpc_ops nfs_v4_clientops = { 2993struct nfs_rpc_ops nfs_v4_clientops = {
2747 .version = 4, /* protocol version */ 2994 .version = 4, /* protocol version */
2748 .dentry_ops = &nfs4_dentry_operations, 2995 .dentry_ops = &nfs4_dentry_operations,
2749 .dir_inode_ops = &nfs4_dir_inode_operations, 2996 .dir_inode_ops = &nfs4_dir_inode_operations,
2997 .file_inode_ops = &nfs4_file_inode_operations,
2750 .getroot = nfs4_proc_get_root, 2998 .getroot = nfs4_proc_get_root,
2751 .getattr = nfs4_proc_getattr, 2999 .getattr = nfs4_proc_getattr,
2752 .setattr = nfs4_proc_setattr, 3000 .setattr = nfs4_proc_setattr,
@@ -2777,6 +3025,7 @@ struct nfs_rpc_ops nfs_v4_clientops = {
2777 .file_open = nfs4_proc_file_open, 3025 .file_open = nfs4_proc_file_open,
2778 .file_release = nfs4_proc_file_release, 3026 .file_release = nfs4_proc_file_release,
2779 .lock = nfs4_proc_lock, 3027 .lock = nfs4_proc_lock,
3028 .clear_acl_cache = nfs4_zap_acl_attr,
2780}; 3029};
2781 3030
2782/* 3031/*
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 667e06f1c647..a3001628ad32 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -53,6 +53,7 @@
53#include <linux/nfs.h> 53#include <linux/nfs.h>
54#include <linux/nfs4.h> 54#include <linux/nfs4.h>
55#include <linux/nfs_fs.h> 55#include <linux/nfs_fs.h>
56#include "nfs4_fs.h"
56 57
57#define NFSDBG_FACILITY NFSDBG_PROC 58#define NFSDBG_FACILITY NFSDBG_PROC
58 59
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 231cebce3c87..afe587d82f1e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -46,24 +46,18 @@
46#include <linux/workqueue.h> 46#include <linux/workqueue.h>
47#include <linux/bitops.h> 47#include <linux/bitops.h>
48 48
49#include "nfs4_fs.h"
49#include "callback.h" 50#include "callback.h"
50#include "delegation.h" 51#include "delegation.h"
51 52
52#define OPENOWNER_POOL_SIZE 8 53#define OPENOWNER_POOL_SIZE 8
53 54
54static DEFINE_SPINLOCK(state_spinlock); 55const nfs4_stateid zero_stateid;
55
56nfs4_stateid zero_stateid;
57
58#if 0
59nfs4_stateid one_stateid =
60 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
61#endif
62 56
57static DEFINE_SPINLOCK(state_spinlock);
63static LIST_HEAD(nfs4_clientid_list); 58static LIST_HEAD(nfs4_clientid_list);
64 59
65static void nfs4_recover_state(void *); 60static void nfs4_recover_state(void *);
66extern void nfs4_renew_state(void *);
67 61
68void 62void
69init_nfsv4_state(struct nfs_server *server) 63init_nfsv4_state(struct nfs_server *server)
@@ -116,6 +110,7 @@ nfs4_alloc_client(struct in_addr *addr)
116 INIT_LIST_HEAD(&clp->cl_superblocks); 110 INIT_LIST_HEAD(&clp->cl_superblocks);
117 init_waitqueue_head(&clp->cl_waitq); 111 init_waitqueue_head(&clp->cl_waitq);
118 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); 112 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
113 clp->cl_rpcclient = ERR_PTR(-EINVAL);
119 clp->cl_boot_time = CURRENT_TIME; 114 clp->cl_boot_time = CURRENT_TIME;
120 clp->cl_state = 1 << NFS4CLNT_OK; 115 clp->cl_state = 1 << NFS4CLNT_OK;
121 return clp; 116 return clp;
@@ -137,7 +132,7 @@ nfs4_free_client(struct nfs4_client *clp)
137 if (clp->cl_cred) 132 if (clp->cl_cred)
138 put_rpccred(clp->cl_cred); 133 put_rpccred(clp->cl_cred);
139 nfs_idmap_delete(clp); 134 nfs_idmap_delete(clp);
140 if (clp->cl_rpcclient) 135 if (!IS_ERR(clp->cl_rpcclient))
141 rpc_shutdown_client(clp->cl_rpcclient); 136 rpc_shutdown_client(clp->cl_rpcclient);
142 kfree(clp); 137 kfree(clp);
143 nfs_callback_down(); 138 nfs_callback_down();
@@ -365,7 +360,7 @@ nfs4_alloc_open_state(void)
365 atomic_set(&state->count, 1); 360 atomic_set(&state->count, 1);
366 INIT_LIST_HEAD(&state->lock_states); 361 INIT_LIST_HEAD(&state->lock_states);
367 init_MUTEX(&state->lock_sema); 362 init_MUTEX(&state->lock_sema);
368 rwlock_init(&state->state_lock); 363 spin_lock_init(&state->state_lock);
369 return state; 364 return state;
370} 365}
371 366
@@ -547,16 +542,6 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
547 return NULL; 542 return NULL;
548} 543}
549 544
550struct nfs4_lock_state *
551nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
552{
553 struct nfs4_lock_state *lsp;
554 read_lock(&state->state_lock);
555 lsp = __nfs4_find_lock_state(state, fl_owner);
556 read_unlock(&state->state_lock);
557 return lsp;
558}
559
560/* 545/*
561 * Return a compatible lock_state. If no initialized lock_state structure 546 * Return a compatible lock_state. If no initialized lock_state structure
562 * exists, return an uninitialized one. 547 * exists, return an uninitialized one.
@@ -573,14 +558,13 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
573 return NULL; 558 return NULL;
574 lsp->ls_flags = 0; 559 lsp->ls_flags = 0;
575 lsp->ls_seqid = 0; /* arbitrary */ 560 lsp->ls_seqid = 0; /* arbitrary */
576 lsp->ls_id = -1;
577 memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data)); 561 memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
578 atomic_set(&lsp->ls_count, 1); 562 atomic_set(&lsp->ls_count, 1);
579 lsp->ls_owner = fl_owner; 563 lsp->ls_owner = fl_owner;
580 INIT_LIST_HEAD(&lsp->ls_locks);
581 spin_lock(&clp->cl_lock); 564 spin_lock(&clp->cl_lock);
582 lsp->ls_id = nfs4_alloc_lockowner_id(clp); 565 lsp->ls_id = nfs4_alloc_lockowner_id(clp);
583 spin_unlock(&clp->cl_lock); 566 spin_unlock(&clp->cl_lock);
567 INIT_LIST_HEAD(&lsp->ls_locks);
584 return lsp; 568 return lsp;
585} 569}
586 570
@@ -590,121 +574,112 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
590 * 574 *
591 * The caller must be holding state->lock_sema and clp->cl_sem 575 * The caller must be holding state->lock_sema and clp->cl_sem
592 */ 576 */
593struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner) 577static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
594{ 578{
595 struct nfs4_lock_state * lsp; 579 struct nfs4_lock_state *lsp, *new = NULL;
596 580
597 lsp = nfs4_find_lock_state(state, owner); 581 for(;;) {
598 if (lsp == NULL) 582 spin_lock(&state->state_lock);
599 lsp = nfs4_alloc_lock_state(state, owner); 583 lsp = __nfs4_find_lock_state(state, owner);
584 if (lsp != NULL)
585 break;
586 if (new != NULL) {
587 new->ls_state = state;
588 list_add(&new->ls_locks, &state->lock_states);
589 set_bit(LK_STATE_IN_USE, &state->flags);
590 lsp = new;
591 new = NULL;
592 break;
593 }
594 spin_unlock(&state->state_lock);
595 new = nfs4_alloc_lock_state(state, owner);
596 if (new == NULL)
597 return NULL;
598 }
599 spin_unlock(&state->state_lock);
600 kfree(new);
600 return lsp; 601 return lsp;
601} 602}
602 603
603/* 604/*
604 * Byte-range lock aware utility to initialize the stateid of read/write 605 * Release reference to lock_state, and free it if we see that
605 * requests. 606 * it is no longer in use
606 */ 607 */
607void 608static void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
608nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
609{ 609{
610 if (test_bit(LK_STATE_IN_USE, &state->flags)) { 610 struct nfs4_state *state;
611 struct nfs4_lock_state *lsp;
612 611
613 lsp = nfs4_find_lock_state(state, fl_owner); 612 if (lsp == NULL)
614 if (lsp) { 613 return;
615 memcpy(dst, &lsp->ls_stateid, sizeof(*dst)); 614 state = lsp->ls_state;
616 nfs4_put_lock_state(lsp); 615 if (!atomic_dec_and_lock(&lsp->ls_count, &state->state_lock))
617 return; 616 return;
618 } 617 list_del(&lsp->ls_locks);
619 } 618 if (list_empty(&state->lock_states))
620 memcpy(dst, &state->stateid, sizeof(*dst)); 619 clear_bit(LK_STATE_IN_USE, &state->flags);
620 spin_unlock(&state->state_lock);
621 kfree(lsp);
621} 622}
622 623
623/* 624static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
624* Called with state->lock_sema and clp->cl_sem held.
625*/
626void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
627{ 625{
628 if (status == NFS_OK || seqid_mutating_err(-status)) 626 struct nfs4_lock_state *lsp = src->fl_u.nfs4_fl.owner;
629 lsp->ls_seqid++;
630}
631 627
632/* 628 dst->fl_u.nfs4_fl.owner = lsp;
633* Check to see if the request lock (type FL_UNLK) effects the fl lock. 629 atomic_inc(&lsp->ls_count);
634* 630}
635* fl and request must have the same posix owner
636*
637* return:
638* 0 -> fl not effected by request
639* 1 -> fl consumed by request
640*/
641 631
642static int 632static void nfs4_fl_release_lock(struct file_lock *fl)
643nfs4_check_unlock(struct file_lock *fl, struct file_lock *request)
644{ 633{
645 if (fl->fl_start >= request->fl_start && fl->fl_end <= request->fl_end) 634 nfs4_put_lock_state(fl->fl_u.nfs4_fl.owner);
646 return 1;
647 return 0;
648} 635}
649 636
650/* 637static struct file_lock_operations nfs4_fl_lock_ops = {
651 * Post an initialized lock_state on the state->lock_states list. 638 .fl_copy_lock = nfs4_fl_copy_lock,
652 */ 639 .fl_release_private = nfs4_fl_release_lock,
653void nfs4_notify_setlk(struct nfs4_state *state, struct file_lock *request, struct nfs4_lock_state *lsp) 640};
641
642int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
654{ 643{
655 if (!list_empty(&lsp->ls_locks)) 644 struct nfs4_lock_state *lsp;
656 return; 645
657 atomic_inc(&lsp->ls_count); 646 if (fl->fl_ops != NULL)
658 write_lock(&state->state_lock); 647 return 0;
659 list_add(&lsp->ls_locks, &state->lock_states); 648 lsp = nfs4_get_lock_state(state, fl->fl_owner);
660 set_bit(LK_STATE_IN_USE, &state->flags); 649 if (lsp == NULL)
661 write_unlock(&state->state_lock); 650 return -ENOMEM;
651 fl->fl_u.nfs4_fl.owner = lsp;
652 fl->fl_ops = &nfs4_fl_lock_ops;
653 return 0;
662} 654}
663 655
664/* 656/*
665 * to decide to 'reap' lock state: 657 * Byte-range lock aware utility to initialize the stateid of read/write
666 * 1) search i_flock for file_locks with fl.lock_state = to ls. 658 * requests.
667 * 2) determine if unlock will consume found lock.
668 * if so, reap
669 *
670 * else, don't reap.
671 *
672 */ 659 */
673void 660void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
674nfs4_notify_unlck(struct nfs4_state *state, struct file_lock *request, struct nfs4_lock_state *lsp)
675{ 661{
676 struct inode *inode = state->inode; 662 struct nfs4_lock_state *lsp;
677 struct file_lock *fl;
678 663
679 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 664 memcpy(dst, &state->stateid, sizeof(*dst));
680 if (!(fl->fl_flags & FL_POSIX)) 665 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
681 continue; 666 return;
682 if (fl->fl_owner != lsp->ls_owner)
683 continue;
684 /* Exit if we find at least one lock which is not consumed */
685 if (nfs4_check_unlock(fl,request) == 0)
686 return;
687 }
688 667
689 write_lock(&state->state_lock); 668 spin_lock(&state->state_lock);
690 list_del_init(&lsp->ls_locks); 669 lsp = __nfs4_find_lock_state(state, fl_owner);
691 if (list_empty(&state->lock_states)) 670 if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
692 clear_bit(LK_STATE_IN_USE, &state->flags); 671 memcpy(dst, &lsp->ls_stateid, sizeof(*dst));
693 write_unlock(&state->state_lock); 672 spin_unlock(&state->state_lock);
694 nfs4_put_lock_state(lsp); 673 nfs4_put_lock_state(lsp);
695} 674}
696 675
697/* 676/*
698 * Release reference to lock_state, and free it if we see that 677* Called with state->lock_sema and clp->cl_sem held.
699 * it is no longer in use 678*/
700 */ 679void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
701void
702nfs4_put_lock_state(struct nfs4_lock_state *lsp)
703{ 680{
704 if (!atomic_dec_and_test(&lsp->ls_count)) 681 if (status == NFS_OK || seqid_mutating_err(-status))
705 return; 682 lsp->ls_seqid++;
706 BUG_ON (!list_empty(&lsp->ls_locks));
707 kfree(lsp);
708} 683}
709 684
710/* 685/*
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5f4de05763c9..6c564ef9489e 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -51,6 +51,7 @@
51#include <linux/nfs4.h> 51#include <linux/nfs4.h>
52#include <linux/nfs_fs.h> 52#include <linux/nfs_fs.h>
53#include <linux/nfs_idmap.h> 53#include <linux/nfs_idmap.h>
54#include "nfs4_fs.h"
54 55
55#define NFSDBG_FACILITY NFSDBG_XDR 56#define NFSDBG_FACILITY NFSDBG_XDR
56 57
@@ -82,12 +83,16 @@ static int nfs_stat_to_errno(int);
82#define encode_getfh_maxsz (op_encode_hdr_maxsz) 83#define encode_getfh_maxsz (op_encode_hdr_maxsz)
83#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ 84#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \
84 ((3+NFS4_FHSIZE) >> 2)) 85 ((3+NFS4_FHSIZE) >> 2))
85#define encode_getattr_maxsz (op_encode_hdr_maxsz + 3) 86#define nfs4_fattr_bitmap_maxsz 3
87#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
86#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) 88#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
87#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) 89#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
88#define nfs4_fattr_bitmap_maxsz (36 + 2 * nfs4_name_maxsz) 90/* This is based on getfattr, which uses the most attributes: */
89#define decode_getattr_maxsz (op_decode_hdr_maxsz + 3 + \ 91#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
90 nfs4_fattr_bitmap_maxsz) 92 3 + 3 + 3 + 2 * nfs4_name_maxsz))
93#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
94 nfs4_fattr_value_maxsz)
95#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
91#define encode_savefh_maxsz (op_encode_hdr_maxsz) 96#define encode_savefh_maxsz (op_encode_hdr_maxsz)
92#define decode_savefh_maxsz (op_decode_hdr_maxsz) 97#define decode_savefh_maxsz (op_decode_hdr_maxsz)
93#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2) 98#define encode_fsinfo_maxsz (op_encode_hdr_maxsz + 2)
@@ -122,11 +127,11 @@ static int nfs_stat_to_errno(int);
122#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ 127#define encode_symlink_maxsz (op_encode_hdr_maxsz + \
123 1 + nfs4_name_maxsz + \ 128 1 + nfs4_name_maxsz + \
124 nfs4_path_maxsz + \ 129 nfs4_path_maxsz + \
125 nfs4_fattr_bitmap_maxsz) 130 nfs4_fattr_maxsz)
126#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) 131#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8)
127#define encode_create_maxsz (op_encode_hdr_maxsz + \ 132#define encode_create_maxsz (op_encode_hdr_maxsz + \
128 2 + nfs4_name_maxsz + \ 133 2 + nfs4_name_maxsz + \
129 nfs4_fattr_bitmap_maxsz) 134 nfs4_fattr_maxsz)
130#define decode_create_maxsz (op_decode_hdr_maxsz + 8) 135#define decode_create_maxsz (op_decode_hdr_maxsz + 8)
131#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4) 136#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
132#define decode_delegreturn_maxsz (op_decode_hdr_maxsz) 137#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
@@ -205,7 +210,7 @@ static int nfs_stat_to_errno(int);
205#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ 210#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
206 encode_putfh_maxsz + \ 211 encode_putfh_maxsz + \
207 op_encode_hdr_maxsz + 4 + \ 212 op_encode_hdr_maxsz + 4 + \
208 nfs4_fattr_bitmap_maxsz + \ 213 nfs4_fattr_maxsz + \
209 encode_getattr_maxsz) 214 encode_getattr_maxsz)
210#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ 215#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
211 decode_putfh_maxsz + \ 216 decode_putfh_maxsz + \
@@ -360,6 +365,20 @@ static int nfs_stat_to_errno(int);
360 encode_delegreturn_maxsz) 365 encode_delegreturn_maxsz)
361#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ 366#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
362 decode_delegreturn_maxsz) 367 decode_delegreturn_maxsz)
368#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
369 encode_putfh_maxsz + \
370 encode_getattr_maxsz)
371#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \
372 decode_putfh_maxsz + \
373 op_decode_hdr_maxsz + \
374 nfs4_fattr_bitmap_maxsz + 1)
375#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \
376 encode_putfh_maxsz + \
377 op_encode_hdr_maxsz + 4 + \
378 nfs4_fattr_bitmap_maxsz + 1)
379#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
380 decode_putfh_maxsz + \
381 op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
363 382
364static struct { 383static struct {
365 unsigned int mode; 384 unsigned int mode;
@@ -459,7 +478,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
459 * In the worst-case, this would be 478 * In the worst-case, this would be
460 * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime) 479 * 12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
461 * = 36 bytes, plus any contribution from variable-length fields 480 * = 36 bytes, plus any contribution from variable-length fields
462 * such as owner/group/acl's. 481 * such as owner/group.
463 */ 482 */
464 len = 16; 483 len = 16;
465 484
@@ -660,8 +679,6 @@ static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1
660 679
661static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask) 680static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask)
662{ 681{
663 extern u32 nfs4_fattr_bitmap[];
664
665 return encode_getattr_two(xdr, 682 return encode_getattr_two(xdr,
666 bitmask[0] & nfs4_fattr_bitmap[0], 683 bitmask[0] & nfs4_fattr_bitmap[0],
667 bitmask[1] & nfs4_fattr_bitmap[1]); 684 bitmask[1] & nfs4_fattr_bitmap[1]);
@@ -669,8 +686,6 @@ static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask)
669 686
670static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask) 687static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask)
671{ 688{
672 extern u32 nfs4_fsinfo_bitmap[];
673
674 return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0], 689 return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0],
675 bitmask[1] & nfs4_fsinfo_bitmap[1]); 690 bitmask[1] & nfs4_fsinfo_bitmap[1]);
676} 691}
@@ -969,7 +984,6 @@ static int encode_putrootfh(struct xdr_stream *xdr)
969 984
970static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx) 985static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
971{ 986{
972 extern nfs4_stateid zero_stateid;
973 nfs4_stateid stateid; 987 nfs4_stateid stateid;
974 uint32_t *p; 988 uint32_t *p;
975 989
@@ -1000,6 +1014,10 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
1000static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req) 1014static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
1001{ 1015{
1002 struct rpc_auth *auth = req->rq_task->tk_auth; 1016 struct rpc_auth *auth = req->rq_task->tk_auth;
1017 uint32_t attrs[2] = {
1018 FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
1019 FATTR4_WORD1_MOUNTED_ON_FILEID,
1020 };
1003 int replen; 1021 int replen;
1004 uint32_t *p; 1022 uint32_t *p;
1005 1023
@@ -1010,13 +1028,20 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1010 WRITE32(readdir->count >> 1); /* We're not doing readdirplus */ 1028 WRITE32(readdir->count >> 1); /* We're not doing readdirplus */
1011 WRITE32(readdir->count); 1029 WRITE32(readdir->count);
1012 WRITE32(2); 1030 WRITE32(2);
1013 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) { 1031 /* Switch to mounted_on_fileid if the server supports it */
1014 WRITE32(0); 1032 if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1015 WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID); 1033 attrs[0] &= ~FATTR4_WORD0_FILEID;
1016 } else { 1034 else
1017 WRITE32(FATTR4_WORD0_FILEID); 1035 attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1018 WRITE32(0); 1036 WRITE32(attrs[0] & readdir->bitmask[0]);
1019 } 1037 WRITE32(attrs[1] & readdir->bitmask[1]);
1038 dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n",
1039 __FUNCTION__,
1040 (unsigned long long)readdir->cookie,
1041 ((u32 *)readdir->verifier.data)[0],
1042 ((u32 *)readdir->verifier.data)[1],
1043 attrs[0] & readdir->bitmask[0],
1044 attrs[1] & readdir->bitmask[1]);
1020 1045
1021 /* set up reply kvec 1046 /* set up reply kvec
1022 * toplevel_status + taglen + rescount + OP_PUTFH + status 1047 * toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1025,6 +1050,9 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
1025 replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2; 1050 replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
1026 xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages, 1051 xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages,
1027 readdir->pgbase, readdir->count); 1052 readdir->pgbase, readdir->count);
1053 dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
1054 __FUNCTION__, replen, readdir->pages,
1055 readdir->pgbase, readdir->count);
1028 1056
1029 return 0; 1057 return 0;
1030} 1058}
@@ -1089,6 +1117,25 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs4_client *client
1089} 1117}
1090 1118
1091static int 1119static int
1120encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
1121{
1122 uint32_t *p;
1123
1124 RESERVE_SPACE(4+sizeof(zero_stateid.data));
1125 WRITE32(OP_SETATTR);
1126 WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
1127 RESERVE_SPACE(2*4);
1128 WRITE32(1);
1129 WRITE32(FATTR4_WORD0_ACL);
1130 if (arg->acl_len % 4)
1131 return -EINVAL;
1132 RESERVE_SPACE(4);
1133 WRITE32(arg->acl_len);
1134 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
1135 return 0;
1136}
1137
1138static int
1092encode_savefh(struct xdr_stream *xdr) 1139encode_savefh(struct xdr_stream *xdr)
1093{ 1140{
1094 uint32_t *p; 1141 uint32_t *p;
@@ -1632,6 +1679,34 @@ out:
1632} 1679}
1633 1680
1634/* 1681/*
1682 * Encode a GETACL request
1683 */
1684static int
1685nfs4_xdr_enc_getacl(struct rpc_rqst *req, uint32_t *p,
1686 struct nfs_getaclargs *args)
1687{
1688 struct xdr_stream xdr;
1689 struct rpc_auth *auth = req->rq_task->tk_auth;
1690 struct compound_hdr hdr = {
1691 .nops = 2,
1692 };
1693 int replen, status;
1694
1695 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1696 encode_compound_hdr(&xdr, &hdr);
1697 status = encode_putfh(&xdr, args->fh);
1698 if (status)
1699 goto out;
1700 status = encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0);
1701 /* set up reply buffer: */
1702 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
1703 xdr_inline_pages(&req->rq_rcv_buf, replen,
1704 args->acl_pages, args->acl_pgbase, args->acl_len);
1705out:
1706 return status;
1707}
1708
1709/*
1635 * Encode a WRITE request 1710 * Encode a WRITE request
1636 */ 1711 */
1637static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args) 1712static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
@@ -1697,7 +1772,6 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs
1697 */ 1772 */
1698static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args) 1773static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args)
1699{ 1774{
1700 extern u32 nfs4_pathconf_bitmap[2];
1701 struct xdr_stream xdr; 1775 struct xdr_stream xdr;
1702 struct compound_hdr hdr = { 1776 struct compound_hdr hdr = {
1703 .nops = 2, 1777 .nops = 2,
@@ -1718,7 +1792,6 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct
1718 */ 1792 */
1719static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args) 1793static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args)
1720{ 1794{
1721 extern u32 nfs4_statfs_bitmap[];
1722 struct xdr_stream xdr; 1795 struct xdr_stream xdr;
1723 struct compound_hdr hdr = { 1796 struct compound_hdr hdr = {
1724 .nops = 2, 1797 .nops = 2,
@@ -3003,6 +3076,11 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3003 return status; 3076 return status;
3004 READ_BUF(8); 3077 READ_BUF(8);
3005 COPYMEM(readdir->verifier.data, 8); 3078 COPYMEM(readdir->verifier.data, 8);
3079 dprintk("%s: verifier = 0x%x%x\n",
3080 __FUNCTION__,
3081 ((u32 *)readdir->verifier.data)[0],
3082 ((u32 *)readdir->verifier.data)[1]);
3083
3006 3084
3007 hdrlen = (char *) p - (char *) iov->iov_base; 3085 hdrlen = (char *) p - (char *) iov->iov_base;
3008 recvd = rcvbuf->len - hdrlen; 3086 recvd = rcvbuf->len - hdrlen;
@@ -3017,12 +3095,14 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
3017 for (nr = 0; *p++; nr++) { 3095 for (nr = 0; *p++; nr++) {
3018 if (p + 3 > end) 3096 if (p + 3 > end)
3019 goto short_pkt; 3097 goto short_pkt;
3098 dprintk("cookie = %Lu, ", *((unsigned long long *)p));
3020 p += 2; /* cookie */ 3099 p += 2; /* cookie */
3021 len = ntohl(*p++); /* filename length */ 3100 len = ntohl(*p++); /* filename length */
3022 if (len > NFS4_MAXNAMLEN) { 3101 if (len > NFS4_MAXNAMLEN) {
3023 printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len); 3102 printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
3024 goto err_unmap; 3103 goto err_unmap;
3025 } 3104 }
3105 dprintk("filename = %*s\n", len, (char *)p);
3026 p += XDR_QUADLEN(len); 3106 p += XDR_QUADLEN(len);
3027 if (p + 1 > end) 3107 if (p + 1 > end)
3028 goto short_pkt; 3108 goto short_pkt;
@@ -3042,6 +3122,7 @@ out:
3042 kunmap_atomic(kaddr, KM_USER0); 3122 kunmap_atomic(kaddr, KM_USER0);
3043 return 0; 3123 return 0;
3044short_pkt: 3124short_pkt:
3125 dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr);
3045 entry[0] = entry[1] = 0; 3126 entry[0] = entry[1] = 0;
3046 /* truncate listing ? */ 3127 /* truncate listing ? */
3047 if (!nr) { 3128 if (!nr) {
@@ -3127,6 +3208,47 @@ static int decode_renew(struct xdr_stream *xdr)
3127 return decode_op_hdr(xdr, OP_RENEW); 3208 return decode_op_hdr(xdr, OP_RENEW);
3128} 3209}
3129 3210
3211static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
3212 size_t *acl_len)
3213{
3214 uint32_t *savep;
3215 uint32_t attrlen,
3216 bitmap[2] = {0};
3217 struct kvec *iov = req->rq_rcv_buf.head;
3218 int status;
3219
3220 *acl_len = 0;
3221 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3222 goto out;
3223 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3224 goto out;
3225 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3226 goto out;
3227
3228 if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
3229 return -EIO;
3230 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
3231 int hdrlen, recvd;
3232
3233 /* We ignore &savep and don't do consistency checks on
3234 * the attr length. Let userspace figure it out.... */
3235 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
3236 recvd = req->rq_rcv_buf.len - hdrlen;
3237 if (attrlen > recvd) {
3238 printk(KERN_WARNING "NFS: server cheating in getattr"
3239 " acl reply: attrlen %u > recvd %u\n",
3240 attrlen, recvd);
3241 return -EINVAL;
3242 }
3243 if (attrlen <= *acl_len)
3244 xdr_read_pages(xdr, attrlen);
3245 *acl_len = attrlen;
3246 }
3247
3248out:
3249 return status;
3250}
3251
3130static int 3252static int
3131decode_savefh(struct xdr_stream *xdr) 3253decode_savefh(struct xdr_stream *xdr)
3132{ 3254{
@@ -3418,6 +3540,71 @@ out:
3418 3540
3419} 3541}
3420 3542
3543/*
3544 * Encode an SETACL request
3545 */
3546static int
3547nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
3548{
3549 struct xdr_stream xdr;
3550 struct compound_hdr hdr = {
3551 .nops = 2,
3552 };
3553 int status;
3554
3555 xdr_init_encode(&xdr, &req->rq_snd_buf, p);
3556 encode_compound_hdr(&xdr, &hdr);
3557 status = encode_putfh(&xdr, args->fh);
3558 if (status)
3559 goto out;
3560 status = encode_setacl(&xdr, args);
3561out:
3562 return status;
3563}
3564/*
3565 * Decode SETACL response
3566 */
3567static int
3568nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
3569{
3570 struct xdr_stream xdr;
3571 struct compound_hdr hdr;
3572 int status;
3573
3574 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3575 status = decode_compound_hdr(&xdr, &hdr);
3576 if (status)
3577 goto out;
3578 status = decode_putfh(&xdr);
3579 if (status)
3580 goto out;
3581 status = decode_setattr(&xdr, res);
3582out:
3583 return status;
3584}
3585
3586/*
3587 * Decode GETACL response
3588 */
3589static int
3590nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, uint32_t *p, size_t *acl_len)
3591{
3592 struct xdr_stream xdr;
3593 struct compound_hdr hdr;
3594 int status;
3595
3596 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3597 status = decode_compound_hdr(&xdr, &hdr);
3598 if (status)
3599 goto out;
3600 status = decode_putfh(&xdr);
3601 if (status)
3602 goto out;
3603 status = decode_getacl(&xdr, rqstp, acl_len);
3604
3605out:
3606 return status;
3607}
3421 3608
3422/* 3609/*
3423 * Decode CLOSE response 3610 * Decode CLOSE response
@@ -3895,6 +4082,12 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
3895 } 4082 }
3896 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */ 4083 len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
3897 if (len > 0) { 4084 if (len > 0) {
4085 if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
4086 bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
4087 /* Ignore the return value of rdattr_error for now */
4088 p++;
4089 len--;
4090 }
3898 if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID) 4091 if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
3899 xdr_decode_hyper(p, &entry->ino); 4092 xdr_decode_hyper(p, &entry->ino);
3900 else if (bitmap[0] == FATTR4_WORD0_FILEID) 4093 else if (bitmap[0] == FATTR4_WORD0_FILEID)
@@ -3934,6 +4127,8 @@ static struct {
3934 { NFS4ERR_DQUOT, EDQUOT }, 4127 { NFS4ERR_DQUOT, EDQUOT },
3935 { NFS4ERR_STALE, ESTALE }, 4128 { NFS4ERR_STALE, ESTALE },
3936 { NFS4ERR_BADHANDLE, EBADHANDLE }, 4129 { NFS4ERR_BADHANDLE, EBADHANDLE },
4130 { NFS4ERR_BADOWNER, EINVAL },
4131 { NFS4ERR_BADNAME, EINVAL },
3937 { NFS4ERR_BAD_COOKIE, EBADCOOKIE }, 4132 { NFS4ERR_BAD_COOKIE, EBADCOOKIE },
3938 { NFS4ERR_NOTSUPP, ENOTSUPP }, 4133 { NFS4ERR_NOTSUPP, ENOTSUPP },
3939 { NFS4ERR_TOOSMALL, ETOOSMALL }, 4134 { NFS4ERR_TOOSMALL, ETOOSMALL },
@@ -4019,6 +4214,8 @@ struct rpc_procinfo nfs4_procedures[] = {
4019 PROC(READDIR, enc_readdir, dec_readdir), 4214 PROC(READDIR, enc_readdir, dec_readdir),
4020 PROC(SERVER_CAPS, enc_server_caps, dec_server_caps), 4215 PROC(SERVER_CAPS, enc_server_caps, dec_server_caps),
4021 PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), 4216 PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn),
4217 PROC(GETACL, enc_getacl, dec_getacl),
4218 PROC(SETACL, enc_setacl, dec_setacl),
4022}; 4219};
4023 4220
4024struct rpc_version nfs_version4 = { 4221struct rpc_version nfs_version4 = {
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index fd5bc596fe8a..1b272a135a31 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -124,6 +124,7 @@ enum {
124 Opt_soft, Opt_hard, Opt_intr, 124 Opt_soft, Opt_hard, Opt_intr,
125 Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, 125 Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
126 Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, 126 Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
127 Opt_acl, Opt_noacl,
127 /* Error token */ 128 /* Error token */
128 Opt_err 129 Opt_err
129}; 130};
@@ -158,6 +159,8 @@ static match_table_t __initdata tokens = {
158 {Opt_udp, "udp"}, 159 {Opt_udp, "udp"},
159 {Opt_tcp, "proto=tcp"}, 160 {Opt_tcp, "proto=tcp"},
160 {Opt_tcp, "tcp"}, 161 {Opt_tcp, "tcp"},
162 {Opt_acl, "acl"},
163 {Opt_noacl, "noacl"},
161 {Opt_err, NULL} 164 {Opt_err, NULL}
162 165
163}; 166};
@@ -266,6 +269,12 @@ static int __init root_nfs_parse(char *name, char *buf)
266 case Opt_tcp: 269 case Opt_tcp:
267 nfs_data.flags |= NFS_MOUNT_TCP; 270 nfs_data.flags |= NFS_MOUNT_TCP;
268 break; 271 break;
272 case Opt_acl:
273 nfs_data.flags &= ~NFS_MOUNT_NOACL;
274 break;
275 case Opt_noacl:
276 nfs_data.flags |= NFS_MOUNT_NOACL;
277 break;
269 default : 278 default :
270 return 0; 279 return 0;
271 } 280 }
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 4f1ba723848d..d53857b148e2 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -107,11 +107,38 @@ void nfs_unlock_request(struct nfs_page *req)
107 smp_mb__before_clear_bit(); 107 smp_mb__before_clear_bit();
108 clear_bit(PG_BUSY, &req->wb_flags); 108 clear_bit(PG_BUSY, &req->wb_flags);
109 smp_mb__after_clear_bit(); 109 smp_mb__after_clear_bit();
110 wake_up_all(&req->wb_context->waitq); 110 wake_up_bit(&req->wb_flags, PG_BUSY);
111 nfs_release_request(req); 111 nfs_release_request(req);
112} 112}
113 113
114/** 114/**
115 * nfs_set_page_writeback_locked - Lock a request for writeback
116 * @req:
117 */
118int nfs_set_page_writeback_locked(struct nfs_page *req)
119{
120 struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
121
122 if (!nfs_lock_request(req))
123 return 0;
124 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
125 return 1;
126}
127
128/**
129 * nfs_clear_page_writeback - Unlock request and wake up sleepers
130 */
131void nfs_clear_page_writeback(struct nfs_page *req)
132{
133 struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
134
135 spin_lock(&nfsi->req_lock);
136 radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
137 spin_unlock(&nfsi->req_lock);
138 nfs_unlock_request(req);
139}
140
141/**
115 * nfs_clear_request - Free up all resources allocated to the request 142 * nfs_clear_request - Free up all resources allocated to the request
116 * @req: 143 * @req:
117 * 144 *
@@ -150,34 +177,15 @@ nfs_release_request(struct nfs_page *req)
150 nfs_page_free(req); 177 nfs_page_free(req);
151} 178}
152 179
153/** 180static int nfs_wait_bit_interruptible(void *word)
154 * nfs_list_add_request - Insert a request into a sorted list
155 * @req: request
156 * @head: head of list into which to insert the request.
157 *
158 * Note that the wb_list is sorted by page index in order to facilitate
159 * coalescing of requests.
160 * We use an insertion sort that is optimized for the case of appended
161 * writes.
162 */
163void
164nfs_list_add_request(struct nfs_page *req, struct list_head *head)
165{ 181{
166 struct list_head *pos; 182 int ret = 0;
167 183
168#ifdef NFS_PARANOIA 184 if (signal_pending(current))
169 if (!list_empty(&req->wb_list)) { 185 ret = -ERESTARTSYS;
170 printk(KERN_ERR "NFS: Add to list failed!\n"); 186 else
171 BUG(); 187 schedule();
172 } 188 return ret;
173#endif
174 list_for_each_prev(pos, head) {
175 struct nfs_page *p = nfs_list_entry(pos);
176 if (p->wb_index < req->wb_index)
177 break;
178 }
179 list_add(&req->wb_list, pos);
180 req->wb_list_head = head;
181} 189}
182 190
183/** 191/**
@@ -190,12 +198,22 @@ nfs_list_add_request(struct nfs_page *req, struct list_head *head)
190int 198int
191nfs_wait_on_request(struct nfs_page *req) 199nfs_wait_on_request(struct nfs_page *req)
192{ 200{
193 struct inode *inode = req->wb_context->dentry->d_inode; 201 struct rpc_clnt *clnt = NFS_CLIENT(req->wb_context->dentry->d_inode);
194 struct rpc_clnt *clnt = NFS_CLIENT(inode); 202 sigset_t oldmask;
195 203 int ret = 0;
196 if (!NFS_WBACK_BUSY(req)) 204
197 return 0; 205 if (!test_bit(PG_BUSY, &req->wb_flags))
198 return nfs_wait_event(clnt, req->wb_context->waitq, !NFS_WBACK_BUSY(req)); 206 goto out;
207 /*
208 * Note: the call to rpc_clnt_sigmask() suffices to ensure that we
209 * are not interrupted if intr flag is not set
210 */
211 rpc_clnt_sigmask(clnt, &oldmask);
212 ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
213 nfs_wait_bit_interruptible, TASK_INTERRUPTIBLE);
214 rpc_clnt_sigunmask(clnt, &oldmask);
215out:
216 return ret;
199} 217}
200 218
201/** 219/**
@@ -243,6 +261,62 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst,
243 return npages; 261 return npages;
244} 262}
245 263
264#define NFS_SCAN_MAXENTRIES 16
265/**
266 * nfs_scan_lock_dirty - Scan the radix tree for dirty requests
267 * @nfsi: NFS inode
268 * @dst: Destination list
269 * @idx_start: lower bound of page->index to scan
270 * @npages: idx_start + npages sets the upper bound to scan.
271 *
272 * Moves elements from one of the inode request lists.
273 * If the number of requests is set to 0, the entire address_space
274 * starting at index idx_start, is scanned.
275 * The requests are *not* checked to ensure that they form a contiguous set.
276 * You must be holding the inode's req_lock when calling this function
277 */
278int
279nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
280 unsigned long idx_start, unsigned int npages)
281{
282 struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
283 struct nfs_page *req;
284 unsigned long idx_end;
285 int found, i;
286 int res;
287
288 res = 0;
289 if (npages == 0)
290 idx_end = ~0;
291 else
292 idx_end = idx_start + npages - 1;
293
294 for (;;) {
295 found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree,
296 (void **)&pgvec[0], idx_start, NFS_SCAN_MAXENTRIES,
297 NFS_PAGE_TAG_DIRTY);
298 if (found <= 0)
299 break;
300 for (i = 0; i < found; i++) {
301 req = pgvec[i];
302 if (req->wb_index > idx_end)
303 goto out;
304
305 idx_start = req->wb_index + 1;
306
307 if (nfs_set_page_writeback_locked(req)) {
308 radix_tree_tag_clear(&nfsi->nfs_page_tree,
309 req->wb_index, NFS_PAGE_TAG_DIRTY);
310 nfs_list_remove_request(req);
311 nfs_list_add_request(req, dst);
312 res++;
313 }
314 }
315 }
316out:
317 return res;
318}
319
246/** 320/**
247 * nfs_scan_list - Scan a list for matching requests 321 * nfs_scan_list - Scan a list for matching requests
248 * @head: One of the NFS inode request lists 322 * @head: One of the NFS inode request lists
@@ -280,7 +354,7 @@ nfs_scan_list(struct list_head *head, struct list_head *dst,
280 if (req->wb_index > idx_end) 354 if (req->wb_index > idx_end)
281 break; 355 break;
282 356
283 if (!nfs_lock_request(req)) 357 if (!nfs_set_page_writeback_locked(req))
284 continue; 358 continue;
285 nfs_list_remove_request(req); 359 nfs_list_remove_request(req);
286 nfs_list_add_request(req, dst); 360 nfs_list_add_request(req, dst);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index d31b4d6e5a5e..cedf636bcf3c 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -622,6 +622,7 @@ struct nfs_rpc_ops nfs_v2_clientops = {
622 .version = 2, /* protocol version */ 622 .version = 2, /* protocol version */
623 .dentry_ops = &nfs_dentry_operations, 623 .dentry_ops = &nfs_dentry_operations,
624 .dir_inode_ops = &nfs_dir_inode_operations, 624 .dir_inode_ops = &nfs_dir_inode_operations,
625 .file_inode_ops = &nfs_file_inode_operations,
625 .getroot = nfs_proc_get_root, 626 .getroot = nfs_proc_get_root,
626 .getattr = nfs_proc_getattr, 627 .getattr = nfs_proc_getattr,
627 .setattr = nfs_proc_setattr, 628 .setattr = nfs_proc_setattr,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index a0042fb58634..6f866b8aa2d5 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -173,7 +173,6 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
173 if (len < PAGE_CACHE_SIZE) 173 if (len < PAGE_CACHE_SIZE)
174 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); 174 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
175 175
176 nfs_lock_request(new);
177 nfs_list_add_request(new, &one_request); 176 nfs_list_add_request(new, &one_request);
178 nfs_pagein_one(&one_request, inode); 177 nfs_pagein_one(&one_request, inode);
179 return 0; 178 return 0;
@@ -185,7 +184,6 @@ static void nfs_readpage_release(struct nfs_page *req)
185 184
186 nfs_clear_request(req); 185 nfs_clear_request(req);
187 nfs_release_request(req); 186 nfs_release_request(req);
188 nfs_unlock_request(req);
189 187
190 dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", 188 dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
191 req->wb_context->dentry->d_inode->i_sb->s_id, 189 req->wb_context->dentry->d_inode->i_sb->s_id,
@@ -553,7 +551,6 @@ readpage_async_filler(void *data, struct page *page)
553 } 551 }
554 if (len < PAGE_CACHE_SIZE) 552 if (len < PAGE_CACHE_SIZE)
555 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); 553 memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
556 nfs_lock_request(new);
557 nfs_list_add_request(new, desc->head); 554 nfs_list_add_request(new, desc->head);
558 return 0; 555 return 0;
559} 556}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 6f7a4af3bc46..5130eda231d7 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -220,7 +220,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
220 ClearPageError(page); 220 ClearPageError(page);
221 221
222io_error: 222io_error:
223 nfs_end_data_update_defer(inode); 223 nfs_end_data_update(inode);
224 nfs_writedata_free(wdata); 224 nfs_writedata_free(wdata);
225 return written ? written : result; 225 return written ? written : result;
226} 226}
@@ -352,7 +352,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
352 if (err < 0) 352 if (err < 0)
353 goto out; 353 goto out;
354 } 354 }
355 err = nfs_commit_inode(inode, 0, 0, wb_priority(wbc)); 355 err = nfs_commit_inode(inode, wb_priority(wbc));
356 if (err > 0) { 356 if (err > 0) {
357 wbc->nr_to_write -= err; 357 wbc->nr_to_write -= err;
358 err = 0; 358 err = 0;
@@ -401,7 +401,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
401 nfsi->npages--; 401 nfsi->npages--;
402 if (!nfsi->npages) { 402 if (!nfsi->npages) {
403 spin_unlock(&nfsi->req_lock); 403 spin_unlock(&nfsi->req_lock);
404 nfs_end_data_update_defer(inode); 404 nfs_end_data_update(inode);
405 iput(inode); 405 iput(inode);
406 } else 406 } else
407 spin_unlock(&nfsi->req_lock); 407 spin_unlock(&nfsi->req_lock);
@@ -446,6 +446,8 @@ nfs_mark_request_dirty(struct nfs_page *req)
446 struct nfs_inode *nfsi = NFS_I(inode); 446 struct nfs_inode *nfsi = NFS_I(inode);
447 447
448 spin_lock(&nfsi->req_lock); 448 spin_lock(&nfsi->req_lock);
449 radix_tree_tag_set(&nfsi->nfs_page_tree,
450 req->wb_index, NFS_PAGE_TAG_DIRTY);
449 nfs_list_add_request(req, &nfsi->dirty); 451 nfs_list_add_request(req, &nfsi->dirty);
450 nfsi->ndirty++; 452 nfsi->ndirty++;
451 spin_unlock(&nfsi->req_lock); 453 spin_unlock(&nfsi->req_lock);
@@ -503,13 +505,12 @@ nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, unsigned int
503 505
504 spin_lock(&nfsi->req_lock); 506 spin_lock(&nfsi->req_lock);
505 next = idx_start; 507 next = idx_start;
506 while (radix_tree_gang_lookup(&nfsi->nfs_page_tree, (void **)&req, next, 1)) { 508 while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_WRITEBACK)) {
507 if (req->wb_index > idx_end) 509 if (req->wb_index > idx_end)
508 break; 510 break;
509 511
510 next = req->wb_index + 1; 512 next = req->wb_index + 1;
511 if (!NFS_WBACK_BUSY(req)) 513 BUG_ON(!NFS_WBACK_BUSY(req));
512 continue;
513 514
514 atomic_inc(&req->wb_count); 515 atomic_inc(&req->wb_count);
515 spin_unlock(&nfsi->req_lock); 516 spin_unlock(&nfsi->req_lock);
@@ -538,12 +539,15 @@ static int
538nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) 539nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages)
539{ 540{
540 struct nfs_inode *nfsi = NFS_I(inode); 541 struct nfs_inode *nfsi = NFS_I(inode);
541 int res; 542 int res = 0;
542 res = nfs_scan_list(&nfsi->dirty, dst, idx_start, npages); 543
543 nfsi->ndirty -= res; 544 if (nfsi->ndirty != 0) {
544 sub_page_state(nr_dirty,res); 545 res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages);
545 if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) 546 nfsi->ndirty -= res;
546 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); 547 sub_page_state(nr_dirty,res);
548 if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty))
549 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n");
550 }
547 return res; 551 return res;
548} 552}
549 553
@@ -562,11 +566,14 @@ static int
562nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) 566nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages)
563{ 567{
564 struct nfs_inode *nfsi = NFS_I(inode); 568 struct nfs_inode *nfsi = NFS_I(inode);
565 int res; 569 int res = 0;
566 res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages); 570
567 nfsi->ncommit -= res; 571 if (nfsi->ncommit != 0) {
568 if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit)) 572 res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages);
569 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n"); 573 nfsi->ncommit -= res;
574 if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
575 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
576 }
570 return res; 577 return res;
571} 578}
572#endif 579#endif
@@ -750,7 +757,7 @@ int nfs_updatepage(struct file *file, struct page *page,
750 * is entirely in cache, it may be more efficient to avoid 757 * is entirely in cache, it may be more efficient to avoid
751 * fragmenting write requests. 758 * fragmenting write requests.
752 */ 759 */
753 if (PageUptodate(page) && inode->i_flock == NULL) { 760 if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
754 loff_t end_offs = i_size_read(inode) - 1; 761 loff_t end_offs = i_size_read(inode) - 1;
755 unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; 762 unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT;
756 763
@@ -821,7 +828,7 @@ out:
821#else 828#else
822 nfs_inode_remove_request(req); 829 nfs_inode_remove_request(req);
823#endif 830#endif
824 nfs_unlock_request(req); 831 nfs_clear_page_writeback(req);
825} 832}
826 833
827static inline int flush_task_priority(int how) 834static inline int flush_task_priority(int how)
@@ -952,7 +959,7 @@ out_bad:
952 nfs_writedata_free(data); 959 nfs_writedata_free(data);
953 } 960 }
954 nfs_mark_request_dirty(req); 961 nfs_mark_request_dirty(req);
955 nfs_unlock_request(req); 962 nfs_clear_page_writeback(req);
956 return -ENOMEM; 963 return -ENOMEM;
957} 964}
958 965
@@ -1002,7 +1009,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
1002 struct nfs_page *req = nfs_list_entry(head->next); 1009 struct nfs_page *req = nfs_list_entry(head->next);
1003 nfs_list_remove_request(req); 1010 nfs_list_remove_request(req);
1004 nfs_mark_request_dirty(req); 1011 nfs_mark_request_dirty(req);
1005 nfs_unlock_request(req); 1012 nfs_clear_page_writeback(req);
1006 } 1013 }
1007 return -ENOMEM; 1014 return -ENOMEM;
1008} 1015}
@@ -1029,7 +1036,7 @@ nfs_flush_list(struct list_head *head, int wpages, int how)
1029 req = nfs_list_entry(head->next); 1036 req = nfs_list_entry(head->next);
1030 nfs_list_remove_request(req); 1037 nfs_list_remove_request(req);
1031 nfs_mark_request_dirty(req); 1038 nfs_mark_request_dirty(req);
1032 nfs_unlock_request(req); 1039 nfs_clear_page_writeback(req);
1033 } 1040 }
1034 return error; 1041 return error;
1035} 1042}
@@ -1121,7 +1128,7 @@ static void nfs_writeback_done_full(struct nfs_write_data *data, int status)
1121 nfs_inode_remove_request(req); 1128 nfs_inode_remove_request(req);
1122#endif 1129#endif
1123 next: 1130 next:
1124 nfs_unlock_request(req); 1131 nfs_clear_page_writeback(req);
1125 } 1132 }
1126} 1133}
1127 1134
@@ -1210,36 +1217,24 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1210 struct nfs_write_data *data, int how) 1217 struct nfs_write_data *data, int how)
1211{ 1218{
1212 struct rpc_task *task = &data->task; 1219 struct rpc_task *task = &data->task;
1213 struct nfs_page *first, *last; 1220 struct nfs_page *first;
1214 struct inode *inode; 1221 struct inode *inode;
1215 loff_t start, end, len;
1216 1222
1217 /* Set up the RPC argument and reply structs 1223 /* Set up the RPC argument and reply structs
1218 * NB: take care not to mess about with data->commit et al. */ 1224 * NB: take care not to mess about with data->commit et al. */
1219 1225
1220 list_splice_init(head, &data->pages); 1226 list_splice_init(head, &data->pages);
1221 first = nfs_list_entry(data->pages.next); 1227 first = nfs_list_entry(data->pages.next);
1222 last = nfs_list_entry(data->pages.prev);
1223 inode = first->wb_context->dentry->d_inode; 1228 inode = first->wb_context->dentry->d_inode;
1224 1229
1225 /*
1226 * Determine the offset range of requests in the COMMIT call.
1227 * We rely on the fact that data->pages is an ordered list...
1228 */
1229 start = req_offset(first);
1230 end = req_offset(last) + last->wb_bytes;
1231 len = end - start;
1232 /* If 'len' is not a 32-bit quantity, pass '0' in the COMMIT call */
1233 if (end >= i_size_read(inode) || len < 0 || len > (~((u32)0) >> 1))
1234 len = 0;
1235
1236 data->inode = inode; 1230 data->inode = inode;
1237 data->cred = first->wb_context->cred; 1231 data->cred = first->wb_context->cred;
1238 1232
1239 data->args.fh = NFS_FH(data->inode); 1233 data->args.fh = NFS_FH(data->inode);
1240 data->args.offset = start; 1234 /* Note: we always request a commit of the entire inode */
1241 data->args.count = len; 1235 data->args.offset = 0;
1242 data->res.count = len; 1236 data->args.count = 0;
1237 data->res.count = 0;
1243 data->res.fattr = &data->fattr; 1238 data->res.fattr = &data->fattr;
1244 data->res.verf = &data->verf; 1239 data->res.verf = &data->verf;
1245 1240
@@ -1278,7 +1273,7 @@ nfs_commit_list(struct list_head *head, int how)
1278 req = nfs_list_entry(head->next); 1273 req = nfs_list_entry(head->next);
1279 nfs_list_remove_request(req); 1274 nfs_list_remove_request(req);
1280 nfs_mark_request_commit(req); 1275 nfs_mark_request_commit(req);
1281 nfs_unlock_request(req); 1276 nfs_clear_page_writeback(req);
1282 } 1277 }
1283 return -ENOMEM; 1278 return -ENOMEM;
1284} 1279}
@@ -1324,7 +1319,7 @@ nfs_commit_done(struct rpc_task *task)
1324 dprintk(" mismatch\n"); 1319 dprintk(" mismatch\n");
1325 nfs_mark_request_dirty(req); 1320 nfs_mark_request_dirty(req);
1326 next: 1321 next:
1327 nfs_unlock_request(req); 1322 nfs_clear_page_writeback(req);
1328 res++; 1323 res++;
1329 } 1324 }
1330 sub_page_state(nr_unstable,res); 1325 sub_page_state(nr_unstable,res);
@@ -1342,16 +1337,23 @@ static int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
1342 spin_lock(&nfsi->req_lock); 1337 spin_lock(&nfsi->req_lock);
1343 res = nfs_scan_dirty(inode, &head, idx_start, npages); 1338 res = nfs_scan_dirty(inode, &head, idx_start, npages);
1344 spin_unlock(&nfsi->req_lock); 1339 spin_unlock(&nfsi->req_lock);
1345 if (res) 1340 if (res) {
1346 error = nfs_flush_list(&head, NFS_SERVER(inode)->wpages, how); 1341 struct nfs_server *server = NFS_SERVER(inode);
1342
1343 /* For single writes, FLUSH_STABLE is more efficient */
1344 if (res == nfsi->npages && nfsi->npages <= server->wpages) {
1345 if (res > 1 || nfs_list_entry(head.next)->wb_bytes <= server->wsize)
1346 how |= FLUSH_STABLE;
1347 }
1348 error = nfs_flush_list(&head, server->wpages, how);
1349 }
1347 if (error < 0) 1350 if (error < 0)
1348 return error; 1351 return error;
1349 return res; 1352 return res;
1350} 1353}
1351 1354
1352#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1355#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
1353int nfs_commit_inode(struct inode *inode, unsigned long idx_start, 1356int nfs_commit_inode(struct inode *inode, int how)
1354 unsigned int npages, int how)
1355{ 1357{
1356 struct nfs_inode *nfsi = NFS_I(inode); 1358 struct nfs_inode *nfsi = NFS_I(inode);
1357 LIST_HEAD(head); 1359 LIST_HEAD(head);
@@ -1359,15 +1361,13 @@ int nfs_commit_inode(struct inode *inode, unsigned long idx_start,
1359 error = 0; 1361 error = 0;
1360 1362
1361 spin_lock(&nfsi->req_lock); 1363 spin_lock(&nfsi->req_lock);
1362 res = nfs_scan_commit(inode, &head, idx_start, npages); 1364 res = nfs_scan_commit(inode, &head, 0, 0);
1365 spin_unlock(&nfsi->req_lock);
1363 if (res) { 1366 if (res) {
1364 res += nfs_scan_commit(inode, &head, 0, 0);
1365 spin_unlock(&nfsi->req_lock);
1366 error = nfs_commit_list(&head, how); 1367 error = nfs_commit_list(&head, how);
1367 } else 1368 if (error < 0)
1368 spin_unlock(&nfsi->req_lock); 1369 return error;
1369 if (error < 0) 1370 }
1370 return error;
1371 return res; 1371 return res;
1372} 1372}
1373#endif 1373#endif
@@ -1389,7 +1389,7 @@ int nfs_sync_inode(struct inode *inode, unsigned long idx_start,
1389 error = nfs_flush_inode(inode, idx_start, npages, how); 1389 error = nfs_flush_inode(inode, idx_start, npages, how);
1390#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1390#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
1391 if (error == 0) 1391 if (error == 0)
1392 error = nfs_commit_inode(inode, idx_start, npages, how); 1392 error = nfs_commit_inode(inode, how);
1393#endif 1393#endif
1394 } while (error > 0); 1394 } while (error > 0);
1395 return error; 1395 return error;
diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile
new file mode 100644
index 000000000000..f689ed82af3a
--- /dev/null
+++ b/fs/nfs_common/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for Linux filesystem routines that are shared by client and server.
3#
4
5obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
6
7nfs_acl-objs := nfsacl.o
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
new file mode 100644
index 000000000000..18c58c32e326
--- /dev/null
+++ b/fs/nfs_common/nfsacl.c
@@ -0,0 +1,257 @@
1/*
2 * fs/nfs_common/nfsacl.c
3 *
4 * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
5 */
6
7/*
8 * The Solaris nfsacl protocol represents some ACLs slightly differently
9 * than POSIX 1003.1e draft 17 does (and we do):
10 *
11 * - Minimal ACLs always have an ACL_MASK entry, so they have
12 * four instead of three entries.
13 * - The ACL_MASK entry in such minimal ACLs always has the same
14 * permissions as the ACL_GROUP_OBJ entry. (In extended ACLs
15 * the ACL_MASK and ACL_GROUP_OBJ entries may differ.)
16 * - The identifier fields of the ACL_USER_OBJ and ACL_GROUP_OBJ
17 * entries contain the identifiers of the owner and owning group.
18 * (In POSIX ACLs we always set them to ACL_UNDEFINED_ID).
19 * - ACL entries in the kernel are kept sorted in ascending order
20 * of (e_tag, e_id). Solaris ACLs are unsorted.
21 */
22
23#include <linux/module.h>
24#include <linux/fs.h>
25#include <linux/sunrpc/xdr.h>
26#include <linux/nfsacl.h>
27#include <linux/nfs3.h>
28#include <linux/sort.h>
29
30MODULE_LICENSE("GPL");
31
32EXPORT_SYMBOL(nfsacl_encode);
33EXPORT_SYMBOL(nfsacl_decode);
34
35struct nfsacl_encode_desc {
36 struct xdr_array2_desc desc;
37 unsigned int count;
38 struct posix_acl *acl;
39 int typeflag;
40 uid_t uid;
41 gid_t gid;
42};
43
44static int
45xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
46{
47 struct nfsacl_encode_desc *nfsacl_desc =
48 (struct nfsacl_encode_desc *) desc;
49 u32 *p = (u32 *) elem;
50
51 if (nfsacl_desc->count < nfsacl_desc->acl->a_count) {
52 struct posix_acl_entry *entry =
53 &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
54
55 *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
56 switch(entry->e_tag) {
57 case ACL_USER_OBJ:
58 *p++ = htonl(nfsacl_desc->uid);
59 break;
60 case ACL_GROUP_OBJ:
61 *p++ = htonl(nfsacl_desc->gid);
62 break;
63 case ACL_USER:
64 case ACL_GROUP:
65 *p++ = htonl(entry->e_id);
66 break;
67 default: /* Solaris depends on that! */
68 *p++ = 0;
69 break;
70 }
71 *p++ = htonl(entry->e_perm & S_IRWXO);
72 } else {
73 const struct posix_acl_entry *pa, *pe;
74 int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
75
76 FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
77 if (pa->e_tag == ACL_GROUP_OBJ) {
78 group_obj_perm = pa->e_perm & S_IRWXO;
79 break;
80 }
81 }
82 /* fake up ACL_MASK entry */
83 *p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
84 *p++ = htonl(0);
85 *p++ = htonl(group_obj_perm);
86 }
87
88 return 0;
89}
90
91unsigned int
92nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
93 struct posix_acl *acl, int encode_entries, int typeflag)
94{
95 int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
96 struct nfsacl_encode_desc nfsacl_desc = {
97 .desc = {
98 .elem_size = 12,
99 .array_len = encode_entries ? entries : 0,
100 .xcode = xdr_nfsace_encode,
101 },
102 .acl = acl,
103 .typeflag = typeflag,
104 .uid = inode->i_uid,
105 .gid = inode->i_gid,
106 };
107 int err;
108
109 if (entries > NFS_ACL_MAX_ENTRIES ||
110 xdr_encode_word(buf, base, entries))
111 return -EINVAL;
112 err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
113 if (!err)
114 err = 8 + nfsacl_desc.desc.elem_size *
115 nfsacl_desc.desc.array_len;
116 return err;
117}
118
119struct nfsacl_decode_desc {
120 struct xdr_array2_desc desc;
121 unsigned int count;
122 struct posix_acl *acl;
123};
124
125static int
126xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
127{
128 struct nfsacl_decode_desc *nfsacl_desc =
129 (struct nfsacl_decode_desc *) desc;
130 u32 *p = (u32 *) elem;
131 struct posix_acl_entry *entry;
132
133 if (!nfsacl_desc->acl) {
134 if (desc->array_len > NFS_ACL_MAX_ENTRIES)
135 return -EINVAL;
136 nfsacl_desc->acl = posix_acl_alloc(desc->array_len, GFP_KERNEL);
137 if (!nfsacl_desc->acl)
138 return -ENOMEM;
139 nfsacl_desc->count = 0;
140 }
141
142 entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
143 entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT;
144 entry->e_id = ntohl(*p++);
145 entry->e_perm = ntohl(*p++);
146
147 switch(entry->e_tag) {
148 case ACL_USER_OBJ:
149 case ACL_USER:
150 case ACL_GROUP_OBJ:
151 case ACL_GROUP:
152 case ACL_OTHER:
153 if (entry->e_perm & ~S_IRWXO)
154 return -EINVAL;
155 break;
156 case ACL_MASK:
157 /* Solaris sometimes sets additonal bits in the mask */
158 entry->e_perm &= S_IRWXO;
159 break;
160 default:
161 return -EINVAL;
162 }
163
164 return 0;
165}
166
167static int
168cmp_acl_entry(const void *x, const void *y)
169{
170 const struct posix_acl_entry *a = x, *b = y;
171
172 if (a->e_tag != b->e_tag)
173 return a->e_tag - b->e_tag;
174 else if (a->e_id > b->e_id)
175 return 1;
176 else if (a->e_id < b->e_id)
177 return -1;
178 else
179 return 0;
180}
181
182/*
183 * Convert from a Solaris ACL to a POSIX 1003.1e draft 17 ACL.
184 */
185static int
186posix_acl_from_nfsacl(struct posix_acl *acl)
187{
188 struct posix_acl_entry *pa, *pe,
189 *group_obj = NULL, *mask = NULL;
190
191 if (!acl)
192 return 0;
193
194 sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry),
195 cmp_acl_entry, NULL);
196
197 /* Clear undefined identifier fields and find the ACL_GROUP_OBJ
198 and ACL_MASK entries. */
199 FOREACH_ACL_ENTRY(pa, acl, pe) {
200 switch(pa->e_tag) {
201 case ACL_USER_OBJ:
202 pa->e_id = ACL_UNDEFINED_ID;
203 break;
204 case ACL_GROUP_OBJ:
205 pa->e_id = ACL_UNDEFINED_ID;
206 group_obj = pa;
207 break;
208 case ACL_MASK:
209 mask = pa;
210 /* fall through */
211 case ACL_OTHER:
212 pa->e_id = ACL_UNDEFINED_ID;
213 break;
214 }
215 }
216 if (acl->a_count == 4 && group_obj && mask &&
217 mask->e_perm == group_obj->e_perm) {
218 /* remove bogus ACL_MASK entry */
219 memmove(mask, mask+1, (3 - (mask - acl->a_entries)) *
220 sizeof(struct posix_acl_entry));
221 acl->a_count = 3;
222 }
223 return 0;
224}
225
226unsigned int
227nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
228 struct posix_acl **pacl)
229{
230 struct nfsacl_decode_desc nfsacl_desc = {
231 .desc = {
232 .elem_size = 12,
233 .xcode = pacl ? xdr_nfsace_decode : NULL,
234 },
235 };
236 u32 entries;
237 int err;
238
239 if (xdr_decode_word(buf, base, &entries) ||
240 entries > NFS_ACL_MAX_ENTRIES)
241 return -EINVAL;
242 err = xdr_decode_array2(buf, base + 4, &nfsacl_desc.desc);
243 if (err)
244 return err;
245 if (pacl) {
246 if (entries != nfsacl_desc.desc.array_len ||
247 posix_acl_from_nfsacl(nfsacl_desc.acl) != 0) {
248 posix_acl_release(nfsacl_desc.acl);
249 return -EINVAL;
250 }
251 *pacl = nfsacl_desc.acl;
252 }
253 if (aclcnt)
254 *aclcnt = entries;
255 return 8 + nfsacl_desc.desc.elem_size *
256 nfsacl_desc.desc.array_len;
257}
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile
index b8680a247f8b..9f043f44c92f 100644
--- a/fs/nfsd/Makefile
+++ b/fs/nfsd/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_NFSD) += nfsd.o
6 6
7nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ 7nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \
8 export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o 8 export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
9nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
9nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o 10nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
11nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
10nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ 12nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
11 nfs4acl.o nfs4callback.o 13 nfs4acl.o nfs4callback.o
12nfsd-objs := $(nfsd-y) 14nfsd-objs := $(nfsd-y)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
new file mode 100644
index 000000000000..7cbf0682b2f0
--- /dev/null
+++ b/fs/nfsd/nfs2acl.c
@@ -0,0 +1,336 @@
1/*
2 * linux/fs/nfsd/nfsacl.c
3 *
4 * Process version 2 NFSACL requests.
5 *
6 * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
7 */
8
9#include <linux/sunrpc/svc.h>
10#include <linux/nfs.h>
11#include <linux/nfsd/nfsd.h>
12#include <linux/nfsd/cache.h>
13#include <linux/nfsd/xdr.h>
14#include <linux/nfsd/xdr3.h>
15#include <linux/posix_acl.h>
16#include <linux/nfsacl.h>
17
18#define NFSDDBG_FACILITY NFSDDBG_PROC
19#define RETURN_STATUS(st) { resp->status = (st); return (st); }
20
21/*
22 * NULL call.
23 */
24static int
25nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
26{
27 return nfs_ok;
28}
29
30/*
31 * Get the Access and/or Default ACL of a file.
32 */
33static int nfsacld_proc_getacl(struct svc_rqst * rqstp,
34 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
35{
36 svc_fh *fh;
37 struct posix_acl *acl;
38 int nfserr = 0;
39
40 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
41
42 fh = fh_copy(&resp->fh, &argp->fh);
43 if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
44 RETURN_STATUS(nfserr_inval);
45
46 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
47 RETURN_STATUS(nfserr_inval);
48 resp->mask = argp->mask;
49
50 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
51 acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
52 if (IS_ERR(acl)) {
53 int err = PTR_ERR(acl);
54
55 if (err == -ENODATA || err == -EOPNOTSUPP)
56 acl = NULL;
57 else {
58 nfserr = nfserrno(err);
59 goto fail;
60 }
61 }
62 if (acl == NULL) {
63 /* Solaris returns the inode's minimum ACL. */
64
65 struct inode *inode = fh->fh_dentry->d_inode;
66 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
67 }
68 resp->acl_access = acl;
69 }
70 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
71 /* Check how Solaris handles requests for the Default ACL
72 of a non-directory! */
73
74 acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
75 if (IS_ERR(acl)) {
76 int err = PTR_ERR(acl);
77
78 if (err == -ENODATA || err == -EOPNOTSUPP)
79 acl = NULL;
80 else {
81 nfserr = nfserrno(err);
82 goto fail;
83 }
84 }
85 resp->acl_default = acl;
86 }
87
88 /* resp->acl_{access,default} are released in nfssvc_release_getacl. */
89 RETURN_STATUS(0);
90
91fail:
92 posix_acl_release(resp->acl_access);
93 posix_acl_release(resp->acl_default);
94 RETURN_STATUS(nfserr);
95}
96
97/*
98 * Set the Access and/or Default ACL of a file.
99 */
100static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
101 struct nfsd3_setaclargs *argp,
102 struct nfsd_attrstat *resp)
103{
104 svc_fh *fh;
105 int nfserr = 0;
106
107 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
108
109 fh = fh_copy(&resp->fh, &argp->fh);
110 nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
111
112 if (!nfserr) {
113 nfserr = nfserrno( nfsd_set_posix_acl(
114 fh, ACL_TYPE_ACCESS, argp->acl_access) );
115 }
116 if (!nfserr) {
117 nfserr = nfserrno( nfsd_set_posix_acl(
118 fh, ACL_TYPE_DEFAULT, argp->acl_default) );
119 }
120
121 /* argp->acl_{access,default} may have been allocated in
122 nfssvc_decode_setaclargs. */
123 posix_acl_release(argp->acl_access);
124 posix_acl_release(argp->acl_default);
125 return nfserr;
126}
127
128/*
129 * Check file attributes
130 */
131static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
132 struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
133{
134 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
135
136 fh_copy(&resp->fh, &argp->fh);
137 return fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
138}
139
140/*
141 * Check file access
142 */
143static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
144 struct nfsd3_accessres *resp)
145{
146 int nfserr;
147
148 dprintk("nfsd: ACCESS(2acl) %s 0x%x\n",
149 SVCFH_fmt(&argp->fh),
150 argp->access);
151
152 fh_copy(&resp->fh, &argp->fh);
153 resp->access = argp->access;
154 nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
155 return nfserr;
156}
157
158/*
159 * XDR decode functions
160 */
161static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
162 struct nfsd3_getaclargs *argp)
163{
164 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
165 return 0;
166 argp->mask = ntohl(*p); p++;
167
168 return xdr_argsize_check(rqstp, p);
169}
170
171
172static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
173 struct nfsd3_setaclargs *argp)
174{
175 struct kvec *head = rqstp->rq_arg.head;
176 unsigned int base;
177 int n;
178
179 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
180 return 0;
181 argp->mask = ntohl(*p++);
182 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
183 !xdr_argsize_check(rqstp, p))
184 return 0;
185
186 base = (char *)p - (char *)head->iov_base;
187 n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
188 (argp->mask & NFS_ACL) ?
189 &argp->acl_access : NULL);
190 if (n > 0)
191 n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
192 (argp->mask & NFS_DFACL) ?
193 &argp->acl_default : NULL);
194 return (n > 0);
195}
196
197static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
198 struct nfsd_fhandle *argp)
199{
200 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
201 return 0;
202 return xdr_argsize_check(rqstp, p);
203}
204
205static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
206 struct nfsd3_accessargs *argp)
207{
208 if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
209 return 0;
210 argp->access = ntohl(*p++);
211
212 return xdr_argsize_check(rqstp, p);
213}
214
215/*
216 * XDR encode functions
217 */
218
219/* GETACL */
220static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
221 struct nfsd3_getaclres *resp)
222{
223 struct dentry *dentry = resp->fh.fh_dentry;
224 struct inode *inode = dentry->d_inode;
225 int w = nfsacl_size(
226 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
227 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
228 struct kvec *head = rqstp->rq_res.head;
229 unsigned int base;
230 int n;
231
232 if (dentry == NULL || dentry->d_inode == NULL)
233 return 0;
234 inode = dentry->d_inode;
235
236 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
237 *p++ = htonl(resp->mask);
238 if (!xdr_ressize_check(rqstp, p))
239 return 0;
240 base = (char *)p - (char *)head->iov_base;
241
242 rqstp->rq_res.page_len = w;
243 while (w > 0) {
244 if (!svc_take_res_page(rqstp))
245 return 0;
246 w -= PAGE_SIZE;
247 }
248
249 n = nfsacl_encode(&rqstp->rq_res, base, inode,
250 resp->acl_access,
251 resp->mask & NFS_ACL, 0);
252 if (n > 0)
253 n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
254 resp->acl_default,
255 resp->mask & NFS_DFACL,
256 NFS_ACL_DEFAULT);
257 if (n <= 0)
258 return 0;
259 return 1;
260}
261
262static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
263 struct nfsd_attrstat *resp)
264{
265 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
266 return xdr_ressize_check(rqstp, p);
267}
268
269/* ACCESS */
270static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
271 struct nfsd3_accessres *resp)
272{
273 p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
274 *p++ = htonl(resp->access);
275 return xdr_ressize_check(rqstp, p);
276}
277
278/*
279 * XDR release functions
280 */
281static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
282 struct nfsd3_getaclres *resp)
283{
284 fh_put(&resp->fh);
285 posix_acl_release(resp->acl_access);
286 posix_acl_release(resp->acl_default);
287 return 1;
288}
289
290static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
291 struct nfsd_fhandle *resp)
292{
293 fh_put(&resp->fh);
294 return 1;
295}
296
297#define nfsaclsvc_decode_voidargs NULL
298#define nfsaclsvc_encode_voidres NULL
299#define nfsaclsvc_release_void NULL
300#define nfsd3_fhandleargs nfsd_fhandle
301#define nfsd3_attrstatres nfsd_attrstat
302#define nfsd3_voidres nfsd3_voidargs
303struct nfsd3_voidargs { int dummy; };
304
305#define PROC(name, argt, rest, relt, cache, respsize) \
306 { (svc_procfunc) nfsacld_proc_##name, \
307 (kxdrproc_t) nfsaclsvc_decode_##argt##args, \
308 (kxdrproc_t) nfsaclsvc_encode_##rest##res, \
309 (kxdrproc_t) nfsaclsvc_release_##relt, \
310 sizeof(struct nfsd3_##argt##args), \
311 sizeof(struct nfsd3_##rest##res), \
312 0, \
313 cache, \
314 respsize, \
315 }
316
317#define ST 1 /* status*/
318#define AT 21 /* attributes */
319#define pAT (1+AT) /* post attributes - conditional */
320#define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */
321
322static struct svc_procedure nfsd_acl_procedures2[] = {
323 PROC(null, void, void, void, RC_NOCACHE, ST),
324 PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)),
325 PROC(setacl, setacl, attrstat, fhandle, RC_NOCACHE, ST+AT),
326 PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, ST+AT),
327 PROC(access, access, access, fhandle, RC_NOCACHE, ST+AT+1),
328};
329
330struct svc_version nfsd_acl_version2 = {
331 .vs_vers = 2,
332 .vs_nproc = 5,
333 .vs_proc = nfsd_acl_procedures2,
334 .vs_dispatch = nfsd_dispatch,
335 .vs_xdrsize = NFS3_SVC_XDRSIZE,
336};
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
new file mode 100644
index 000000000000..64ba40572fea
--- /dev/null
+++ b/fs/nfsd/nfs3acl.c
@@ -0,0 +1,267 @@
1/*
2 * linux/fs/nfsd/nfs3acl.c
3 *
4 * Process version 3 NFSACL requests.
5 *
6 * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
7 */
8
9#include <linux/sunrpc/svc.h>
10#include <linux/nfs3.h>
11#include <linux/nfsd/nfsd.h>
12#include <linux/nfsd/cache.h>
13#include <linux/nfsd/xdr3.h>
14#include <linux/posix_acl.h>
15#include <linux/nfsacl.h>
16
17#define RETURN_STATUS(st) { resp->status = (st); return (st); }
18
19/*
20 * NULL call.
21 */
22static int
23nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
24{
25 return nfs_ok;
26}
27
28/*
29 * Get the Access and/or Default ACL of a file.
30 */
31static int nfsd3_proc_getacl(struct svc_rqst * rqstp,
32 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
33{
34 svc_fh *fh;
35 struct posix_acl *acl;
36 int nfserr = 0;
37
38 fh = fh_copy(&resp->fh, &argp->fh);
39 if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
40 RETURN_STATUS(nfserr_inval);
41
42 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
43 RETURN_STATUS(nfserr_inval);
44 resp->mask = argp->mask;
45
46 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
47 acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
48 if (IS_ERR(acl)) {
49 int err = PTR_ERR(acl);
50
51 if (err == -ENODATA || err == -EOPNOTSUPP)
52 acl = NULL;
53 else {
54 nfserr = nfserrno(err);
55 goto fail;
56 }
57 }
58 if (acl == NULL) {
59 /* Solaris returns the inode's minimum ACL. */
60
61 struct inode *inode = fh->fh_dentry->d_inode;
62 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
63 }
64 resp->acl_access = acl;
65 }
66 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
67 /* Check how Solaris handles requests for the Default ACL
68 of a non-directory! */
69
70 acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
71 if (IS_ERR(acl)) {
72 int err = PTR_ERR(acl);
73
74 if (err == -ENODATA || err == -EOPNOTSUPP)
75 acl = NULL;
76 else {
77 nfserr = nfserrno(err);
78 goto fail;
79 }
80 }
81 resp->acl_default = acl;
82 }
83
84 /* resp->acl_{access,default} are released in nfs3svc_release_getacl. */
85 RETURN_STATUS(0);
86
87fail:
88 posix_acl_release(resp->acl_access);
89 posix_acl_release(resp->acl_default);
90 RETURN_STATUS(nfserr);
91}
92
93/*
94 * Set the Access and/or Default ACL of a file.
95 */
96static int nfsd3_proc_setacl(struct svc_rqst * rqstp,
97 struct nfsd3_setaclargs *argp,
98 struct nfsd3_attrstat *resp)
99{
100 svc_fh *fh;
101 int nfserr = 0;
102
103 fh = fh_copy(&resp->fh, &argp->fh);
104 nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
105
106 if (!nfserr) {
107 nfserr = nfserrno( nfsd_set_posix_acl(
108 fh, ACL_TYPE_ACCESS, argp->acl_access) );
109 }
110 if (!nfserr) {
111 nfserr = nfserrno( nfsd_set_posix_acl(
112 fh, ACL_TYPE_DEFAULT, argp->acl_default) );
113 }
114
115 /* argp->acl_{access,default} may have been allocated in
116 nfs3svc_decode_setaclargs. */
117 posix_acl_release(argp->acl_access);
118 posix_acl_release(argp->acl_default);
119 RETURN_STATUS(nfserr);
120}
121
122/*
123 * XDR decode functions
124 */
125static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
126 struct nfsd3_getaclargs *args)
127{
128 if (!(p = nfs3svc_decode_fh(p, &args->fh)))
129 return 0;
130 args->mask = ntohl(*p); p++;
131
132 return xdr_argsize_check(rqstp, p);
133}
134
135
136static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
137 struct nfsd3_setaclargs *args)
138{
139 struct kvec *head = rqstp->rq_arg.head;
140 unsigned int base;
141 int n;
142
143 if (!(p = nfs3svc_decode_fh(p, &args->fh)))
144 return 0;
145 args->mask = ntohl(*p++);
146 if (args->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
147 !xdr_argsize_check(rqstp, p))
148 return 0;
149
150 base = (char *)p - (char *)head->iov_base;
151 n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
152 (args->mask & NFS_ACL) ?
153 &args->acl_access : NULL);
154 if (n > 0)
155 n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
156 (args->mask & NFS_DFACL) ?
157 &args->acl_default : NULL);
158 return (n > 0);
159}
160
161/*
162 * XDR encode functions
163 */
164
165/* GETACL */
166static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
167 struct nfsd3_getaclres *resp)
168{
169 struct dentry *dentry = resp->fh.fh_dentry;
170
171 p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
172 if (resp->status == 0 && dentry && dentry->d_inode) {
173 struct inode *inode = dentry->d_inode;
174 int w = nfsacl_size(
175 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
176 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
177 struct kvec *head = rqstp->rq_res.head;
178 unsigned int base;
179 int n;
180
181 *p++ = htonl(resp->mask);
182 if (!xdr_ressize_check(rqstp, p))
183 return 0;
184 base = (char *)p - (char *)head->iov_base;
185
186 rqstp->rq_res.page_len = w;
187 while (w > 0) {
188 if (!svc_take_res_page(rqstp))
189 return 0;
190 w -= PAGE_SIZE;
191 }
192
193 n = nfsacl_encode(&rqstp->rq_res, base, inode,
194 resp->acl_access,
195 resp->mask & NFS_ACL, 0);
196 if (n > 0)
197 n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
198 resp->acl_default,
199 resp->mask & NFS_DFACL,
200 NFS_ACL_DEFAULT);
201 if (n <= 0)
202 return 0;
203 } else
204 if (!xdr_ressize_check(rqstp, p))
205 return 0;
206
207 return 1;
208}
209
210/* SETACL */
211static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p,
212 struct nfsd3_attrstat *resp)
213{
214 p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
215
216 return xdr_ressize_check(rqstp, p);
217}
218
219/*
220 * XDR release functions
221 */
222static int nfs3svc_release_getacl(struct svc_rqst *rqstp, u32 *p,
223 struct nfsd3_getaclres *resp)
224{
225 fh_put(&resp->fh);
226 posix_acl_release(resp->acl_access);
227 posix_acl_release(resp->acl_default);
228 return 1;
229}
230
231#define nfs3svc_decode_voidargs NULL
232#define nfs3svc_release_void NULL
233#define nfsd3_setaclres nfsd3_attrstat
234#define nfsd3_voidres nfsd3_voidargs
235struct nfsd3_voidargs { int dummy; };
236
237#define PROC(name, argt, rest, relt, cache, respsize) \
238 { (svc_procfunc) nfsd3_proc_##name, \
239 (kxdrproc_t) nfs3svc_decode_##argt##args, \
240 (kxdrproc_t) nfs3svc_encode_##rest##res, \
241 (kxdrproc_t) nfs3svc_release_##relt, \
242 sizeof(struct nfsd3_##argt##args), \
243 sizeof(struct nfsd3_##rest##res), \
244 0, \
245 cache, \
246 respsize, \
247 }
248
249#define ST 1 /* status*/
250#define AT 21 /* attributes */
251#define pAT (1+AT) /* post attributes - conditional */
252#define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */
253
254static struct svc_procedure nfsd_acl_procedures3[] = {
255 PROC(null, void, void, void, RC_NOCACHE, ST),
256 PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)),
257 PROC(setacl, setacl, setacl, fhandle, RC_NOCACHE, ST+pAT),
258};
259
260struct svc_version nfsd_acl_version3 = {
261 .vs_vers = 3,
262 .vs_nproc = 3,
263 .vs_proc = nfsd_acl_procedures3,
264 .vs_dispatch = nfsd_dispatch,
265 .vs_xdrsize = NFS3_SVC_XDRSIZE,
266};
267
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 11f806835c5a..e0e134d6baba 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -71,6 +71,12 @@ decode_fh(u32 *p, struct svc_fh *fhp)
71 return p + XDR_QUADLEN(size); 71 return p + XDR_QUADLEN(size);
72} 72}
73 73
74/* Helper function for NFSv3 ACL code */
75u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp)
76{
77 return decode_fh(p, fhp);
78}
79
74static inline u32 * 80static inline u32 *
75encode_fh(u32 *p, struct svc_fh *fhp) 81encode_fh(u32 *p, struct svc_fh *fhp)
76{ 82{
@@ -233,6 +239,13 @@ encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
233 return p; 239 return p;
234} 240}
235 241
242/* Helper for NFSv3 ACLs */
243u32 *
244nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
245{
246 return encode_post_op_attr(rqstp, p, fhp);
247}
248
236/* 249/*
237 * Enocde weak cache consistency data 250 * Enocde weak cache consistency data
238 */ 251 */
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 1a55dfcb74bc..634465e9cfc6 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -430,7 +430,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
430 clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX); 430 clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
431 if (IS_ERR(clnt)) { 431 if (IS_ERR(clnt)) {
432 dprintk("NFSD: couldn't create callback client\n"); 432 dprintk("NFSD: couldn't create callback client\n");
433 goto out_xprt; 433 goto out_err;
434 } 434 }
435 clnt->cl_intr = 0; 435 clnt->cl_intr = 0;
436 clnt->cl_softrtry = 1; 436 clnt->cl_softrtry = 1;
@@ -465,8 +465,6 @@ out_rpciod:
465out_clnt: 465out_clnt:
466 rpc_shutdown_client(clnt); 466 rpc_shutdown_client(clnt);
467 goto out_err; 467 goto out_err;
468out_xprt:
469 xprt_destroy(xprt);
470out_err: 468out_err:
471 dprintk("NFSD: warning: no callback path to client %.*s\n", 469 dprintk("NFSD: warning: no callback path to client %.*s\n",
472 (int)clp->cl_name.len, clp->cl_name.data); 470 (int)clp->cl_name.len, clp->cl_name.data);
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 757f9d208034..0aa1b9603d7f 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -591,6 +591,7 @@ nfserrno (int errno)
591 { nfserr_dropit, -ENOMEM }, 591 { nfserr_dropit, -ENOMEM },
592 { nfserr_badname, -ESRCH }, 592 { nfserr_badname, -ESRCH },
593 { nfserr_io, -ETXTBSY }, 593 { nfserr_io, -ETXTBSY },
594 { nfserr_notsupp, -EOPNOTSUPP },
594 { -1, -EIO } 595 { -1, -EIO }
595 }; 596 };
596 int i; 597 int i;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 02ded7cfbdcf..904df604e86b 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -31,6 +31,7 @@
31#include <linux/nfsd/stats.h> 31#include <linux/nfsd/stats.h>
32#include <linux/nfsd/cache.h> 32#include <linux/nfsd/cache.h>
33#include <linux/lockd/bind.h> 33#include <linux/lockd/bind.h>
34#include <linux/nfsacl.h>
34 35
35#define NFSDDBG_FACILITY NFSDDBG_SVC 36#define NFSDDBG_FACILITY NFSDDBG_SVC
36 37
@@ -362,6 +363,32 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
362 return 1; 363 return 1;
363} 364}
364 365
366#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
367static struct svc_stat nfsd_acl_svcstats;
368static struct svc_version * nfsd_acl_version[] = {
369 [2] = &nfsd_acl_version2,
370 [3] = &nfsd_acl_version3,
371};
372
373#define NFSD_ACL_NRVERS (sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
374static struct svc_program nfsd_acl_program = {
375 .pg_prog = NFS_ACL_PROGRAM,
376 .pg_nvers = NFSD_ACL_NRVERS,
377 .pg_vers = nfsd_acl_version,
378 .pg_name = "nfsd",
379 .pg_class = "nfsd",
380 .pg_stats = &nfsd_acl_svcstats,
381};
382
383static struct svc_stat nfsd_acl_svcstats = {
384 .program = &nfsd_acl_program,
385};
386
387#define nfsd_acl_program_p &nfsd_acl_program
388#else
389#define nfsd_acl_program_p NULL
390#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
391
365extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; 392extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
366 393
367static struct svc_version * nfsd_version[] = { 394static struct svc_version * nfsd_version[] = {
@@ -376,6 +403,7 @@ static struct svc_version * nfsd_version[] = {
376 403
377#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0])) 404#define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
378struct svc_program nfsd_program = { 405struct svc_program nfsd_program = {
406 .pg_next = nfsd_acl_program_p,
379 .pg_prog = NFS_PROGRAM, /* program number */ 407 .pg_prog = NFS_PROGRAM, /* program number */
380 .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ 408 .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
381 .pg_vers = nfsd_version, /* version table */ 409 .pg_vers = nfsd_version, /* version table */
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 948b08287c99..b45999ff33e6 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -49,6 +49,12 @@ decode_fh(u32 *p, struct svc_fh *fhp)
49 return p + (NFS_FHSIZE >> 2); 49 return p + (NFS_FHSIZE >> 2);
50} 50}
51 51
52/* Helper function for NFSv2 ACL code */
53u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp)
54{
55 return decode_fh(p, fhp);
56}
57
52static inline u32 * 58static inline u32 *
53encode_fh(u32 *p, struct svc_fh *fhp) 59encode_fh(u32 *p, struct svc_fh *fhp)
54{ 60{
@@ -190,6 +196,11 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
190 return p; 196 return p;
191} 197}
192 198
199/* Helper function for NFSv2 ACL code */
200u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
201{
202 return encode_fattr(rqstp, p, fhp);
203}
193 204
194/* 205/*
195 * XDR decode functions 206 * XDR decode functions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index e3e9d217236e..ae3940dc85cc 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -46,8 +46,9 @@
46#include <linux/nfsd/nfsfh.h> 46#include <linux/nfsd/nfsfh.h>
47#include <linux/quotaops.h> 47#include <linux/quotaops.h>
48#include <linux/dnotify.h> 48#include <linux/dnotify.h>
49#ifdef CONFIG_NFSD_V4 49#include <linux/xattr_acl.h>
50#include <linux/posix_acl.h> 50#include <linux/posix_acl.h>
51#ifdef CONFIG_NFSD_V4
51#include <linux/posix_acl_xattr.h> 52#include <linux/posix_acl_xattr.h>
52#include <linux/xattr_acl.h> 53#include <linux/xattr_acl.h>
53#include <linux/xattr.h> 54#include <linux/xattr.h>
@@ -1857,3 +1858,107 @@ nfsd_racache_init(int cache_size)
1857 nfsdstats.ra_size = cache_size; 1858 nfsdstats.ra_size = cache_size;
1858 return 0; 1859 return 0;
1859} 1860}
1861
1862#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
1863struct posix_acl *
1864nfsd_get_posix_acl(struct svc_fh *fhp, int type)
1865{
1866 struct inode *inode = fhp->fh_dentry->d_inode;
1867 char *name;
1868 void *value = NULL;
1869 ssize_t size;
1870 struct posix_acl *acl;
1871
1872 if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr)
1873 return ERR_PTR(-EOPNOTSUPP);
1874 switch(type) {
1875 case ACL_TYPE_ACCESS:
1876 name = XATTR_NAME_ACL_ACCESS;
1877 break;
1878 case ACL_TYPE_DEFAULT:
1879 name = XATTR_NAME_ACL_DEFAULT;
1880 break;
1881 default:
1882 return ERR_PTR(-EOPNOTSUPP);
1883 }
1884
1885 size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0);
1886
1887 if (size < 0) {
1888 acl = ERR_PTR(size);
1889 goto getout;
1890 } else if (size > 0) {
1891 value = kmalloc(size, GFP_KERNEL);
1892 if (!value) {
1893 acl = ERR_PTR(-ENOMEM);
1894 goto getout;
1895 }
1896 size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size);
1897 if (size < 0) {
1898 acl = ERR_PTR(size);
1899 goto getout;
1900 }
1901 }
1902 acl = posix_acl_from_xattr(value, size);
1903
1904getout:
1905 kfree(value);
1906 return acl;
1907}
1908
1909int
1910nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
1911{
1912 struct inode *inode = fhp->fh_dentry->d_inode;
1913 char *name;
1914 void *value = NULL;
1915 size_t size;
1916 int error;
1917
1918 if (!IS_POSIXACL(inode) || !inode->i_op ||
1919 !inode->i_op->setxattr || !inode->i_op->removexattr)
1920 return -EOPNOTSUPP;
1921 switch(type) {
1922 case ACL_TYPE_ACCESS:
1923 name = XATTR_NAME_ACL_ACCESS;
1924 break;
1925 case ACL_TYPE_DEFAULT:
1926 name = XATTR_NAME_ACL_DEFAULT;
1927 break;
1928 default:
1929 return -EOPNOTSUPP;
1930 }
1931
1932 if (acl && acl->a_count) {
1933 size = xattr_acl_size(acl->a_count);
1934 value = kmalloc(size, GFP_KERNEL);
1935 if (!value)
1936 return -ENOMEM;
1937 size = posix_acl_to_xattr(acl, value, size);
1938 if (size < 0) {
1939 error = size;
1940 goto getout;
1941 }
1942 } else
1943 size = 0;
1944
1945 if (!fhp->fh_locked)
1946 fh_lock(fhp); /* unlocking is done automatically */
1947 if (size)
1948 error = inode->i_op->setxattr(fhp->fh_dentry, name,
1949 value, size, 0);
1950 else {
1951 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
1952 error = 0;
1953 else {
1954 error = inode->i_op->removexattr(fhp->fh_dentry, name);
1955 if (error == -ENODATA)
1956 error = 0;
1957 }
1958 }
1959
1960getout:
1961 kfree(value);
1962 return error;
1963}
1964#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9b8b696d4f15..e5a8db00df29 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -674,6 +674,7 @@ struct file_lock {
674 struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */ 674 struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */
675 union { 675 union {
676 struct nfs_lock_info nfs_fl; 676 struct nfs_lock_info nfs_fl;
677 struct nfs4_lock_info nfs4_fl;
677 } fl_u; 678 } fl_u;
678}; 679};
679 680
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 0d9d22578212..16d4e5a08e1d 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -72,6 +72,8 @@ struct nlm_lockowner {
72 uint32_t pid; 72 uint32_t pid;
73}; 73};
74 74
75struct nlm_wait;
76
75/* 77/*
76 * Memory chunk for NLM client RPC request. 78 * Memory chunk for NLM client RPC request.
77 */ 79 */
@@ -81,6 +83,7 @@ struct nlm_rqst {
81 struct nlm_host * a_host; /* host handle */ 83 struct nlm_host * a_host; /* host handle */
82 struct nlm_args a_args; /* arguments */ 84 struct nlm_args a_args; /* arguments */
83 struct nlm_res a_res; /* result */ 85 struct nlm_res a_res; /* result */
86 struct nlm_wait * a_block;
84 char a_owner[NLMCLNT_OHSIZE]; 87 char a_owner[NLMCLNT_OHSIZE];
85}; 88};
86 89
@@ -142,7 +145,9 @@ extern unsigned long nlmsvc_timeout;
142 * Lockd client functions 145 * Lockd client functions
143 */ 146 */
144struct nlm_rqst * nlmclnt_alloc_call(void); 147struct nlm_rqst * nlmclnt_alloc_call(void);
145int nlmclnt_block(struct nlm_host *, struct file_lock *, u32 *); 148int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl);
149void nlmclnt_finish_block(struct nlm_rqst *req);
150long nlmclnt_block(struct nlm_rqst *req, long timeout);
146int nlmclnt_cancel(struct nlm_host *, struct file_lock *); 151int nlmclnt_cancel(struct nlm_host *, struct file_lock *);
147u32 nlmclnt_grant(struct nlm_lock *); 152u32 nlmclnt_grant(struct nlm_lock *);
148void nlmclnt_recovery(struct nlm_host *, u32); 153void nlmclnt_recovery(struct nlm_host *, u32);
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 5ca8a8d8ccdf..5bb5b2fd7ba2 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -382,6 +382,8 @@ enum {
382 NFSPROC4_CLNT_READDIR, 382 NFSPROC4_CLNT_READDIR,
383 NFSPROC4_CLNT_SERVER_CAPS, 383 NFSPROC4_CLNT_SERVER_CAPS,
384 NFSPROC4_CLNT_DELEGRETURN, 384 NFSPROC4_CLNT_DELEGRETURN,
385 NFSPROC4_CLNT_GETACL,
386 NFSPROC4_CLNT_SETACL,
385}; 387};
386 388
387#endif 389#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index dbac7f363e5d..8ea249110fb0 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -15,7 +15,6 @@
15#include <linux/pagemap.h> 15#include <linux/pagemap.h>
16#include <linux/rwsem.h> 16#include <linux/rwsem.h>
17#include <linux/wait.h> 17#include <linux/wait.h>
18#include <linux/uio.h>
19 18
20#include <linux/nfs_fs_sb.h> 19#include <linux/nfs_fs_sb.h>
21 20
@@ -29,7 +28,6 @@
29#include <linux/nfs4.h> 28#include <linux/nfs4.h>
30#include <linux/nfs_xdr.h> 29#include <linux/nfs_xdr.h>
31#include <linux/rwsem.h> 30#include <linux/rwsem.h>
32#include <linux/workqueue.h>
33#include <linux/mempool.h> 31#include <linux/mempool.h>
34 32
35/* 33/*
@@ -44,13 +42,6 @@
44#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 42#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096
45 43
46/* 44/*
47 * The upper limit on timeouts for the exponential backoff algorithm.
48 */
49#define NFS_WRITEBACK_DELAY (5*HZ)
50#define NFS_WRITEBACK_LOCKDELAY (60*HZ)
51#define NFS_COMMIT_DELAY (5*HZ)
52
53/*
54 * superblock magic number for NFS 45 * superblock magic number for NFS
55 */ 46 */
56#define NFS_SUPER_MAGIC 0x6969 47#define NFS_SUPER_MAGIC 0x6969
@@ -60,9 +51,6 @@
60 */ 51 */
61#define NFS_RPC_SWAPFLAGS (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS) 52#define NFS_RPC_SWAPFLAGS (RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS)
62 53
63#define NFS_RW_SYNC 0x0001 /* O_SYNC handling */
64#define NFS_RW_SWAP 0x0002 /* This is a swap request */
65
66/* 54/*
67 * When flushing a cluster of dirty pages, there can be different 55 * When flushing a cluster of dirty pages, there can be different
68 * strategies: 56 * strategies:
@@ -96,7 +84,8 @@ struct nfs_open_context {
96 int error; 84 int error;
97 85
98 struct list_head list; 86 struct list_head list;
99 wait_queue_head_t waitq; 87
88 __u64 dir_cookie;
100}; 89};
101 90
102/* 91/*
@@ -104,6 +93,8 @@ struct nfs_open_context {
104 */ 93 */
105struct nfs_delegation; 94struct nfs_delegation;
106 95
96struct posix_acl;
97
107/* 98/*
108 * nfs fs inode data in memory 99 * nfs fs inode data in memory
109 */ 100 */
@@ -140,7 +131,6 @@ struct nfs_inode {
140 * 131 *
141 * mtime != read_cache_mtime 132 * mtime != read_cache_mtime
142 */ 133 */
143 unsigned long readdir_timestamp;
144 unsigned long read_cache_jiffies; 134 unsigned long read_cache_jiffies;
145 unsigned long attrtimeo; 135 unsigned long attrtimeo;
146 unsigned long attrtimeo_timestamp; 136 unsigned long attrtimeo_timestamp;
@@ -158,6 +148,10 @@ struct nfs_inode {
158 atomic_t data_updates; 148 atomic_t data_updates;
159 149
160 struct nfs_access_entry cache_access; 150 struct nfs_access_entry cache_access;
151#ifdef CONFIG_NFS_V3_ACL
152 struct posix_acl *acl_access;
153 struct posix_acl *acl_default;
154#endif
161 155
162 /* 156 /*
163 * This is the cookie verifier used for NFSv3 readdir 157 * This is the cookie verifier used for NFSv3 readdir
@@ -183,13 +177,13 @@ struct nfs_inode {
183 wait_queue_head_t nfs_i_wait; 177 wait_queue_head_t nfs_i_wait;
184 178
185#ifdef CONFIG_NFS_V4 179#ifdef CONFIG_NFS_V4
180 struct nfs4_cached_acl *nfs4_acl;
186 /* NFSv4 state */ 181 /* NFSv4 state */
187 struct list_head open_states; 182 struct list_head open_states;
188 struct nfs_delegation *delegation; 183 struct nfs_delegation *delegation;
189 int delegation_state; 184 int delegation_state;
190 struct rw_semaphore rwsem; 185 struct rw_semaphore rwsem;
191#endif /* CONFIG_NFS_V4*/ 186#endif /* CONFIG_NFS_V4*/
192
193 struct inode vfs_inode; 187 struct inode vfs_inode;
194}; 188};
195 189
@@ -203,6 +197,8 @@ struct nfs_inode {
203#define NFS_INO_INVALID_DATA 0x0010 /* cached data is invalid */ 197#define NFS_INO_INVALID_DATA 0x0010 /* cached data is invalid */
204#define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ 198#define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */
205#define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ 199#define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */
200#define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */
201#define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */
206 202
207static inline struct nfs_inode *NFS_I(struct inode *inode) 203static inline struct nfs_inode *NFS_I(struct inode *inode)
208{ 204{
@@ -294,12 +290,12 @@ extern int nfs_release(struct inode *, struct file *);
294extern int nfs_attribute_timeout(struct inode *inode); 290extern int nfs_attribute_timeout(struct inode *inode);
295extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); 291extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
296extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); 292extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
293extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
297extern int nfs_setattr(struct dentry *, struct iattr *); 294extern int nfs_setattr(struct dentry *, struct iattr *);
298extern void nfs_begin_attr_update(struct inode *); 295extern void nfs_begin_attr_update(struct inode *);
299extern void nfs_end_attr_update(struct inode *); 296extern void nfs_end_attr_update(struct inode *);
300extern void nfs_begin_data_update(struct inode *); 297extern void nfs_begin_data_update(struct inode *);
301extern void nfs_end_data_update(struct inode *); 298extern void nfs_end_data_update(struct inode *);
302extern void nfs_end_data_update_defer(struct inode *);
303extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred); 299extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred);
304extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); 300extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
305extern void put_nfs_open_context(struct nfs_open_context *ctx); 301extern void put_nfs_open_context(struct nfs_open_context *ctx);
@@ -314,6 +310,9 @@ extern u32 root_nfs_parse_addr(char *name); /*__init*/
314 * linux/fs/nfs/file.c 310 * linux/fs/nfs/file.c
315 */ 311 */
316extern struct inode_operations nfs_file_inode_operations; 312extern struct inode_operations nfs_file_inode_operations;
313#ifdef CONFIG_NFS_V3
314extern struct inode_operations nfs3_file_inode_operations;
315#endif /* CONFIG_NFS_V3 */
317extern struct file_operations nfs_file_operations; 316extern struct file_operations nfs_file_operations;
318extern struct address_space_operations nfs_file_aops; 317extern struct address_space_operations nfs_file_aops;
319 318
@@ -329,6 +328,22 @@ static inline struct rpc_cred *nfs_file_cred(struct file *file)
329} 328}
330 329
331/* 330/*
331 * linux/fs/nfs/xattr.c
332 */
333#ifdef CONFIG_NFS_V3_ACL
334extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
335extern ssize_t nfs3_getxattr(struct dentry *, const char *, void *, size_t);
336extern int nfs3_setxattr(struct dentry *, const char *,
337 const void *, size_t, int);
338extern int nfs3_removexattr (struct dentry *, const char *name);
339#else
340# define nfs3_listxattr NULL
341# define nfs3_getxattr NULL
342# define nfs3_setxattr NULL
343# define nfs3_removexattr NULL
344#endif
345
346/*
332 * linux/fs/nfs/direct.c 347 * linux/fs/nfs/direct.c
333 */ 348 */
334extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t, 349extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
@@ -342,6 +357,9 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
342 * linux/fs/nfs/dir.c 357 * linux/fs/nfs/dir.c
343 */ 358 */
344extern struct inode_operations nfs_dir_inode_operations; 359extern struct inode_operations nfs_dir_inode_operations;
360#ifdef CONFIG_NFS_V3
361extern struct inode_operations nfs3_dir_inode_operations;
362#endif /* CONFIG_NFS_V3 */
345extern struct file_operations nfs_dir_operations; 363extern struct file_operations nfs_dir_operations;
346extern struct dentry_operations nfs_dentry_operations; 364extern struct dentry_operations nfs_dentry_operations;
347 365
@@ -377,10 +395,10 @@ extern void nfs_commit_done(struct rpc_task *);
377 */ 395 */
378extern int nfs_sync_inode(struct inode *, unsigned long, unsigned int, int); 396extern int nfs_sync_inode(struct inode *, unsigned long, unsigned int, int);
379#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 397#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
380extern int nfs_commit_inode(struct inode *, unsigned long, unsigned int, int); 398extern int nfs_commit_inode(struct inode *, int);
381#else 399#else
382static inline int 400static inline int
383nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how) 401nfs_commit_inode(struct inode *inode, int how)
384{ 402{
385 return 0; 403 return 0;
386} 404}
@@ -434,11 +452,6 @@ static inline void nfs_writedata_free(struct nfs_write_data *p)
434 mempool_free(p, nfs_wdata_mempool); 452 mempool_free(p, nfs_wdata_mempool);
435} 453}
436 454
437/* Hack for future NFS swap support */
438#ifndef IS_SWAPFILE
439# define IS_SWAPFILE(inode) (0)
440#endif
441
442/* 455/*
443 * linux/fs/nfs/read.c 456 * linux/fs/nfs/read.c
444 */ 457 */
@@ -468,6 +481,29 @@ static inline void nfs_readdata_free(struct nfs_read_data *p)
468extern void nfs_readdata_release(struct rpc_task *task); 481extern void nfs_readdata_release(struct rpc_task *task);
469 482
470/* 483/*
484 * linux/fs/nfs3proc.c
485 */
486#ifdef CONFIG_NFS_V3_ACL
487extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
488extern int nfs3_proc_setacl(struct inode *inode, int type,
489 struct posix_acl *acl);
490extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
491 mode_t mode);
492extern void nfs3_forget_cached_acls(struct inode *inode);
493#else
494static inline int nfs3_proc_set_default_acl(struct inode *dir,
495 struct inode *inode,
496 mode_t mode)
497{
498 return 0;
499}
500
501static inline void nfs3_forget_cached_acls(struct inode *inode)
502{
503}
504#endif /* CONFIG_NFS_V3_ACL */
505
506/*
471 * linux/fs/mount_clnt.c 507 * linux/fs/mount_clnt.c
472 * (Used only by nfsroot module) 508 * (Used only by nfsroot module)
473 */ 509 */
@@ -515,230 +551,6 @@ extern void * nfs_root_data(void);
515 551
516#define NFS_JUKEBOX_RETRY_TIME (5 * HZ) 552#define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
517 553
518#ifdef CONFIG_NFS_V4
519
520struct idmap;
521
522/*
523 * In a seqid-mutating op, this macro controls which error return
524 * values trigger incrementation of the seqid.
525 *
526 * from rfc 3010:
527 * The client MUST monotonically increment the sequence number for the
528 * CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
529 * operations. This is true even in the event that the previous
530 * operation that used the sequence number received an error. The only
531 * exception to this rule is if the previous operation received one of
532 * the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
533 * NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
534 * NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
535 *
536 */
537#define seqid_mutating_err(err) \
538(((err) != NFSERR_STALE_CLIENTID) && \
539 ((err) != NFSERR_STALE_STATEID) && \
540 ((err) != NFSERR_BAD_STATEID) && \
541 ((err) != NFSERR_BAD_SEQID) && \
542 ((err) != NFSERR_BAD_XDR) && \
543 ((err) != NFSERR_RESOURCE) && \
544 ((err) != NFSERR_NOFILEHANDLE))
545
546enum nfs4_client_state {
547 NFS4CLNT_OK = 0,
548};
549
550/*
551 * The nfs4_client identifies our client state to the server.
552 */
553struct nfs4_client {
554 struct list_head cl_servers; /* Global list of servers */
555 struct in_addr cl_addr; /* Server identifier */
556 u64 cl_clientid; /* constant */
557 nfs4_verifier cl_confirm;
558 unsigned long cl_state;
559
560 u32 cl_lockowner_id;
561
562 /*
563 * The following rwsem ensures exclusive access to the server
564 * while we recover the state following a lease expiration.
565 */
566 struct rw_semaphore cl_sem;
567
568 struct list_head cl_delegations;
569 struct list_head cl_state_owners;
570 struct list_head cl_unused;
571 int cl_nunused;
572 spinlock_t cl_lock;
573 atomic_t cl_count;
574
575 struct rpc_clnt * cl_rpcclient;
576 struct rpc_cred * cl_cred;
577
578 struct list_head cl_superblocks; /* List of nfs_server structs */
579
580 unsigned long cl_lease_time;
581 unsigned long cl_last_renewal;
582 struct work_struct cl_renewd;
583 struct work_struct cl_recoverd;
584
585 wait_queue_head_t cl_waitq;
586 struct rpc_wait_queue cl_rpcwaitq;
587
588 /* used for the setclientid verifier */
589 struct timespec cl_boot_time;
590
591 /* idmapper */
592 struct idmap * cl_idmap;
593
594 /* Our own IP address, as a null-terminated string.
595 * This is used to generate the clientid, and the callback address.
596 */
597 char cl_ipaddr[16];
598 unsigned char cl_id_uniquifier;
599};
600
601/*
602 * NFS4 state_owners and lock_owners are simply labels for ordered
603 * sequences of RPC calls. Their sole purpose is to provide once-only
604 * semantics by allowing the server to identify replayed requests.
605 *
606 * The ->so_sema is held during all state_owner seqid-mutating operations:
607 * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
608 * so_seqid.
609 */
610struct nfs4_state_owner {
611 struct list_head so_list; /* per-clientid list of state_owners */
612 struct nfs4_client *so_client;
613 u32 so_id; /* 32-bit identifier, unique */
614 struct semaphore so_sema;
615 u32 so_seqid; /* protected by so_sema */
616 atomic_t so_count;
617
618 struct rpc_cred *so_cred; /* Associated cred */
619 struct list_head so_states;
620 struct list_head so_delegations;
621};
622
623/*
624 * struct nfs4_state maintains the client-side state for a given
625 * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
626 *
627 * OPEN:
628 * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
629 * we need to know how many files are open for reading or writing on a
630 * given inode. This information too is stored here.
631 *
632 * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
633 */
634
635struct nfs4_lock_state {
636 struct list_head ls_locks; /* Other lock stateids */
637 fl_owner_t ls_owner; /* POSIX lock owner */
638#define NFS_LOCK_INITIALIZED 1
639 int ls_flags;
640 u32 ls_seqid;
641 u32 ls_id;
642 nfs4_stateid ls_stateid;
643 atomic_t ls_count;
644};
645
646/* bits for nfs4_state->flags */
647enum {
648 LK_STATE_IN_USE,
649 NFS_DELEGATED_STATE,
650};
651
652struct nfs4_state {
653 struct list_head open_states; /* List of states for the same state_owner */
654 struct list_head inode_states; /* List of states for the same inode */
655 struct list_head lock_states; /* List of subservient lock stateids */
656
657 struct nfs4_state_owner *owner; /* Pointer to the open owner */
658 struct inode *inode; /* Pointer to the inode */
659
660 unsigned long flags; /* Do we hold any locks? */
661 struct semaphore lock_sema; /* Serializes file locking operations */
662 rwlock_t state_lock; /* Protects the lock_states list */
663
664 nfs4_stateid stateid;
665
666 unsigned int nreaders;
667 unsigned int nwriters;
668 int state; /* State on the server (R,W, or RW) */
669 atomic_t count;
670};
671
672
673struct nfs4_exception {
674 long timeout;
675 int retry;
676};
677
678struct nfs4_state_recovery_ops {
679 int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
680 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
681};
682
683extern struct dentry_operations nfs4_dentry_operations;
684extern struct inode_operations nfs4_dir_inode_operations;
685
686/* nfs4proc.c */
687extern int nfs4_map_errors(int err);
688extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
689extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
690extern int nfs4_proc_async_renew(struct nfs4_client *);
691extern int nfs4_proc_renew(struct nfs4_client *);
692extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
693extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
694extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
695
696extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
697extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
698
699/* nfs4renewd.c */
700extern void nfs4_schedule_state_renewal(struct nfs4_client *);
701extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
702extern void nfs4_kill_renewd(struct nfs4_client *);
703
704/* nfs4state.c */
705extern void init_nfsv4_state(struct nfs_server *);
706extern void destroy_nfsv4_state(struct nfs_server *);
707extern struct nfs4_client *nfs4_get_client(struct in_addr *);
708extern void nfs4_put_client(struct nfs4_client *clp);
709extern int nfs4_init_client(struct nfs4_client *clp);
710extern struct nfs4_client *nfs4_find_client(struct in_addr *);
711extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
712
713extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
714extern void nfs4_put_state_owner(struct nfs4_state_owner *);
715extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
716extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
717extern void nfs4_put_open_state(struct nfs4_state *);
718extern void nfs4_close_state(struct nfs4_state *, mode_t);
719extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
720extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
721extern void nfs4_schedule_state_recovery(struct nfs4_client *);
722extern struct nfs4_lock_state *nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t);
723extern struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t);
724extern void nfs4_put_lock_state(struct nfs4_lock_state *state);
725extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
726extern void nfs4_notify_setlk(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
727extern void nfs4_notify_unlck(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
728extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
729
730
731
732struct nfs4_mount_data;
733#else
734#define init_nfsv4_state(server) do { } while (0)
735#define destroy_nfsv4_state(server) do { } while (0)
736#define nfs4_put_state_owner(inode, owner) do { } while (0)
737#define nfs4_put_open_state(state) do { } while (0)
738#define nfs4_close_state(a, b) do { } while (0)
739#define nfs4_renewd_prepare_shutdown(server) do { } while (0)
740#endif
741
742#endif /* __KERNEL__ */ 554#endif /* __KERNEL__ */
743 555
744/* 556/*
diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h
index e9a749588a7b..e2c18dabff86 100644
--- a/include/linux/nfs_fs_i.h
+++ b/include/linux/nfs_fs_i.h
@@ -16,6 +16,11 @@ struct nfs_lock_info {
16 struct nlm_lockowner *owner; 16 struct nlm_lockowner *owner;
17}; 17};
18 18
19struct nfs4_lock_state;
20struct nfs4_lock_info {
21 struct nfs4_lock_state *owner;
22};
23
19/* 24/*
20 * Lock flag values 25 * Lock flag values
21 */ 26 */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index fc51645d61ee..3d3a305488cf 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -10,6 +10,7 @@
10struct nfs_server { 10struct nfs_server {
11 struct rpc_clnt * client; /* RPC client handle */ 11 struct rpc_clnt * client; /* RPC client handle */
12 struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */ 12 struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */
13 struct rpc_clnt * client_acl; /* ACL RPC client handle */
13 struct nfs_rpc_ops * rpc_ops; /* NFS protocol vector */ 14 struct nfs_rpc_ops * rpc_ops; /* NFS protocol vector */
14 struct backing_dev_info backing_dev_info; 15 struct backing_dev_info backing_dev_info;
15 int flags; /* various flags */ 16 int flags; /* various flags */
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
index 0071428231f9..659c75438454 100644
--- a/include/linux/nfs_mount.h
+++ b/include/linux/nfs_mount.h
@@ -58,6 +58,7 @@ struct nfs_mount_data {
58#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */ 58#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
59#define NFS_MOUNT_NONLM 0x0200 /* 3 */ 59#define NFS_MOUNT_NONLM 0x0200 /* 3 */
60#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ 60#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
61#define NFS_MOUNT_NOACL 0x0800 /* 4 */
61#define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ 62#define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
62#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ 63#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
63#define NFS_MOUNT_FLAGMASK 0xFFFF 64#define NFS_MOUNT_FLAGMASK 0xFFFF
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 39e4895bcdb4..da2e077b65e2 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -20,12 +20,19 @@
20#include <asm/atomic.h> 20#include <asm/atomic.h>
21 21
22/* 22/*
23 * Valid flags for the radix tree
24 */
25#define NFS_PAGE_TAG_DIRTY 0
26#define NFS_PAGE_TAG_WRITEBACK 1
27
28/*
23 * Valid flags for a dirty buffer 29 * Valid flags for a dirty buffer
24 */ 30 */
25#define PG_BUSY 0 31#define PG_BUSY 0
26#define PG_NEED_COMMIT 1 32#define PG_NEED_COMMIT 1
27#define PG_NEED_RESCHED 2 33#define PG_NEED_RESCHED 2
28 34
35struct nfs_inode;
29struct nfs_page { 36struct nfs_page {
30 struct list_head wb_list, /* Defines state of page: */ 37 struct list_head wb_list, /* Defines state of page: */
31 *wb_list_head; /* read/write/commit */ 38 *wb_list_head; /* read/write/commit */
@@ -54,14 +61,17 @@ extern void nfs_clear_request(struct nfs_page *req);
54extern void nfs_release_request(struct nfs_page *req); 61extern void nfs_release_request(struct nfs_page *req);
55 62
56 63
57extern void nfs_list_add_request(struct nfs_page *, struct list_head *); 64extern int nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
58 65 unsigned long idx_start, unsigned int npages);
59extern int nfs_scan_list(struct list_head *, struct list_head *, 66extern int nfs_scan_list(struct list_head *, struct list_head *,
60 unsigned long, unsigned int); 67 unsigned long, unsigned int);
61extern int nfs_coalesce_requests(struct list_head *, struct list_head *, 68extern int nfs_coalesce_requests(struct list_head *, struct list_head *,
62 unsigned int); 69 unsigned int);
63extern int nfs_wait_on_request(struct nfs_page *); 70extern int nfs_wait_on_request(struct nfs_page *);
64extern void nfs_unlock_request(struct nfs_page *req); 71extern void nfs_unlock_request(struct nfs_page *req);
72extern int nfs_set_page_writeback_locked(struct nfs_page *req);
73extern void nfs_clear_page_writeback(struct nfs_page *req);
74
65 75
66/* 76/*
67 * Lock the page of an asynchronous request without incrementing the wb_count 77 * Lock the page of an asynchronous request without incrementing the wb_count
@@ -86,6 +96,18 @@ nfs_lock_request(struct nfs_page *req)
86 return 1; 96 return 1;
87} 97}
88 98
99/**
100 * nfs_list_add_request - Insert a request into a list
101 * @req: request
102 * @head: head of list into which to insert the request.
103 */
104static inline void
105nfs_list_add_request(struct nfs_page *req, struct list_head *head)
106{
107 list_add_tail(&req->wb_list, head);
108 req->wb_list_head = head;
109}
110
89 111
90/** 112/**
91 * nfs_list_remove_request - Remove a request from its wb_list 113 * nfs_list_remove_request - Remove a request from its wb_list
@@ -96,10 +118,6 @@ nfs_list_remove_request(struct nfs_page *req)
96{ 118{
97 if (list_empty(&req->wb_list)) 119 if (list_empty(&req->wb_list))
98 return; 120 return;
99 if (!NFS_WBACK_BUSY(req)) {
100 printk(KERN_ERR "NFS: unlocked request attempted removed from list!\n");
101 BUG();
102 }
103 list_del_init(&req->wb_list); 121 list_del_init(&req->wb_list);
104 req->wb_list_head = NULL; 122 req->wb_list_head = NULL;
105} 123}
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 47037d9521cb..a2bf6914ff1b 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -2,6 +2,7 @@
2#define _LINUX_NFS_XDR_H 2#define _LINUX_NFS_XDR_H
3 3
4#include <linux/sunrpc/xprt.h> 4#include <linux/sunrpc/xprt.h>
5#include <linux/nfsacl.h>
5 6
6struct nfs4_fsid { 7struct nfs4_fsid {
7 __u64 major; 8 __u64 major;
@@ -326,6 +327,20 @@ struct nfs_setattrargs {
326 const u32 * bitmask; 327 const u32 * bitmask;
327}; 328};
328 329
330struct nfs_setaclargs {
331 struct nfs_fh * fh;
332 size_t acl_len;
333 unsigned int acl_pgbase;
334 struct page ** acl_pages;
335};
336
337struct nfs_getaclargs {
338 struct nfs_fh * fh;
339 size_t acl_len;
340 unsigned int acl_pgbase;
341 struct page ** acl_pages;
342};
343
329struct nfs_setattrres { 344struct nfs_setattrres {
330 struct nfs_fattr * fattr; 345 struct nfs_fattr * fattr;
331 const struct nfs_server * server; 346 const struct nfs_server * server;
@@ -354,6 +369,20 @@ struct nfs_readdirargs {
354 struct page ** pages; 369 struct page ** pages;
355}; 370};
356 371
372struct nfs3_getaclargs {
373 struct nfs_fh * fh;
374 int mask;
375 struct page ** pages;
376};
377
378struct nfs3_setaclargs {
379 struct inode * inode;
380 int mask;
381 struct posix_acl * acl_access;
382 struct posix_acl * acl_default;
383 struct page ** pages;
384};
385
357struct nfs_diropok { 386struct nfs_diropok {
358 struct nfs_fh * fh; 387 struct nfs_fh * fh;
359 struct nfs_fattr * fattr; 388 struct nfs_fattr * fattr;
@@ -477,6 +506,15 @@ struct nfs3_readdirres {
477 int plus; 506 int plus;
478}; 507};
479 508
509struct nfs3_getaclres {
510 struct nfs_fattr * fattr;
511 int mask;
512 unsigned int acl_access_count;
513 unsigned int acl_default_count;
514 struct posix_acl * acl_access;
515 struct posix_acl * acl_default;
516};
517
480#ifdef CONFIG_NFS_V4 518#ifdef CONFIG_NFS_V4
481 519
482typedef u64 clientid4; 520typedef u64 clientid4;
@@ -667,6 +705,7 @@ struct nfs_rpc_ops {
667 int version; /* Protocol version */ 705 int version; /* Protocol version */
668 struct dentry_operations *dentry_ops; 706 struct dentry_operations *dentry_ops;
669 struct inode_operations *dir_inode_ops; 707 struct inode_operations *dir_inode_ops;
708 struct inode_operations *file_inode_ops;
670 709
671 int (*getroot) (struct nfs_server *, struct nfs_fh *, 710 int (*getroot) (struct nfs_server *, struct nfs_fh *,
672 struct nfs_fsinfo *); 711 struct nfs_fsinfo *);
@@ -713,6 +752,7 @@ struct nfs_rpc_ops {
713 int (*file_open) (struct inode *, struct file *); 752 int (*file_open) (struct inode *, struct file *);
714 int (*file_release) (struct inode *, struct file *); 753 int (*file_release) (struct inode *, struct file *);
715 int (*lock)(struct file *, int, struct file_lock *); 754 int (*lock)(struct file *, int, struct file_lock *);
755 void (*clear_acl_cache)(struct inode *);
716}; 756};
717 757
718/* 758/*
@@ -732,4 +772,7 @@ extern struct rpc_version nfs_version2;
732extern struct rpc_version nfs_version3; 772extern struct rpc_version nfs_version3;
733extern struct rpc_version nfs_version4; 773extern struct rpc_version nfs_version4;
734 774
775extern struct rpc_version nfsacl_version3;
776extern struct rpc_program nfsacl_program;
777
735#endif 778#endif
diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h
new file mode 100644
index 000000000000..54487a99beb8
--- /dev/null
+++ b/include/linux/nfsacl.h
@@ -0,0 +1,58 @@
1/*
2 * File: linux/nfsacl.h
3 *
4 * (C) 2003 Andreas Gruenbacher <agruen@suse.de>
5 */
6#ifndef __LINUX_NFSACL_H
7#define __LINUX_NFSACL_H
8
9#define NFS_ACL_PROGRAM 100227
10
11#define ACLPROC2_GETACL 1
12#define ACLPROC2_SETACL 2
13#define ACLPROC2_GETATTR 3
14#define ACLPROC2_ACCESS 4
15
16#define ACLPROC3_GETACL 1
17#define ACLPROC3_SETACL 2
18
19
20/* Flags for the getacl/setacl mode */
21#define NFS_ACL 0x0001
22#define NFS_ACLCNT 0x0002
23#define NFS_DFACL 0x0004
24#define NFS_DFACLCNT 0x0008
25
26/* Flag for Default ACL entries */
27#define NFS_ACL_DEFAULT 0x1000
28
29#ifdef __KERNEL__
30
31#include <linux/posix_acl.h>
32
33/* Maximum number of ACL entries over NFS */
34#define NFS_ACL_MAX_ENTRIES 1024
35
36#define NFSACL_MAXWORDS (2*(2+3*NFS_ACL_MAX_ENTRIES))
37#define NFSACL_MAXPAGES ((2*(8+12*NFS_ACL_MAX_ENTRIES) + PAGE_SIZE-1) \
38 >> PAGE_SHIFT)
39
40static inline unsigned int
41nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default)
42{
43 unsigned int w = 16;
44 w += max(acl_access ? (int)acl_access->a_count : 3, 4) * 12;
45 if (acl_default)
46 w += max((int)acl_default->a_count, 4) * 12;
47 return w;
48}
49
50extern unsigned int
51nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
52 struct posix_acl *acl, int encode_entries, int typeflag);
53extern unsigned int
54nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
55 struct posix_acl **pacl);
56
57#endif /* __KERNEL__ */
58#endif /* __LINUX_NFSACL_H */
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 8f85d9a59607..4bf931d5ff56 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -15,6 +15,7 @@
15#include <linux/unistd.h> 15#include <linux/unistd.h>
16#include <linux/dirent.h> 16#include <linux/dirent.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/posix_acl.h>
18#include <linux/mount.h> 19#include <linux/mount.h>
19 20
20#include <linux/nfsd/debug.h> 21#include <linux/nfsd/debug.h>
@@ -124,6 +125,21 @@ int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
124int nfsd_notify_change(struct inode *, struct iattr *); 125int nfsd_notify_change(struct inode *, struct iattr *);
125int nfsd_permission(struct svc_export *, struct dentry *, int); 126int nfsd_permission(struct svc_export *, struct dentry *, int);
126 127
128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
129#ifdef CONFIG_NFSD_V2_ACL
130extern struct svc_version nfsd_acl_version2;
131#else
132#define nfsd_acl_version2 NULL
133#endif
134#ifdef CONFIG_NFSD_V3_ACL
135extern struct svc_version nfsd_acl_version3;
136#else
137#define nfsd_acl_version3 NULL
138#endif
139struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
140int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
141#endif
142
127 143
128/* 144/*
129 * NFSv4 State 145 * NFSv4 State
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h
index ecccef777dae..130d4f588a37 100644
--- a/include/linux/nfsd/xdr.h
+++ b/include/linux/nfsd/xdr.h
@@ -169,4 +169,8 @@ int nfssvc_encode_entry(struct readdir_cd *, const char *name,
169 169
170int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *); 170int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
171 171
172/* Helper functions for NFSv2 ACL code */
173u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp);
174u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp);
175
172#endif /* LINUX_NFSD_H */ 176#endif /* LINUX_NFSD_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index 0ae9e0ef5f68..21e18ce7ca63 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -110,6 +110,19 @@ struct nfsd3_commitargs {
110 __u32 count; 110 __u32 count;
111}; 111};
112 112
113struct nfsd3_getaclargs {
114 struct svc_fh fh;
115 int mask;
116};
117
118struct posix_acl;
119struct nfsd3_setaclargs {
120 struct svc_fh fh;
121 int mask;
122 struct posix_acl *acl_access;
123 struct posix_acl *acl_default;
124};
125
113struct nfsd3_attrstat { 126struct nfsd3_attrstat {
114 __u32 status; 127 __u32 status;
115 struct svc_fh fh; 128 struct svc_fh fh;
@@ -209,6 +222,14 @@ struct nfsd3_commitres {
209 struct svc_fh fh; 222 struct svc_fh fh;
210}; 223};
211 224
225struct nfsd3_getaclres {
226 __u32 status;
227 struct svc_fh fh;
228 int mask;
229 struct posix_acl *acl_access;
230 struct posix_acl *acl_default;
231};
232
212/* dummy type for release */ 233/* dummy type for release */
213struct nfsd3_fhandle_pair { 234struct nfsd3_fhandle_pair {
214 __u32 dummy; 235 __u32 dummy;
@@ -241,6 +262,7 @@ union nfsd3_xdrstore {
241 struct nfsd3_fsinfores fsinfores; 262 struct nfsd3_fsinfores fsinfores;
242 struct nfsd3_pathconfres pathconfres; 263 struct nfsd3_pathconfres pathconfres;
243 struct nfsd3_commitres commitres; 264 struct nfsd3_commitres commitres;
265 struct nfsd3_getaclres getaclres;
244}; 266};
245 267
246#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) 268#define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore)
@@ -316,6 +338,10 @@ int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
316int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, 338int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
317 int namlen, loff_t offset, ino_t ino, 339 int namlen, loff_t offset, ino_t ino,
318 unsigned int); 340 unsigned int);
341/* Helper functions for NFSv3 ACL code */
342u32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p,
343 struct svc_fh *fhp);
344u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp);
319 345
320 346
321#endif /* _LINUX_NFSD_XDR3_H */ 347#endif /* _LINUX_NFSD_XDR3_H */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 2709caf4d128..ab151bbb66df 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -111,6 +111,11 @@ struct rpc_procinfo {
111struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname, 111struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
112 struct rpc_program *info, 112 struct rpc_program *info,
113 u32 version, rpc_authflavor_t authflavor); 113 u32 version, rpc_authflavor_t authflavor);
114struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname,
115 struct rpc_program *info,
116 u32 version, rpc_authflavor_t authflavor);
117struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
118 struct rpc_program *, int);
114struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); 119struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
115int rpc_shutdown_client(struct rpc_clnt *); 120int rpc_shutdown_client(struct rpc_clnt *);
116int rpc_destroy_client(struct rpc_clnt *); 121int rpc_destroy_client(struct rpc_clnt *);
@@ -129,6 +134,7 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
129void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); 134void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
130void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); 135void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
131size_t rpc_max_payload(struct rpc_clnt *); 136size_t rpc_max_payload(struct rpc_clnt *);
137int rpc_ping(struct rpc_clnt *clnt, int flags);
132 138
133static __inline__ 139static __inline__
134int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags) 140int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 99d17ed7cebb..4d77e90d0b30 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -31,7 +31,6 @@ struct rpc_wait_queue;
31struct rpc_wait { 31struct rpc_wait {
32 struct list_head list; /* wait queue links */ 32 struct list_head list; /* wait queue links */
33 struct list_head links; /* Links to related tasks */ 33 struct list_head links; /* Links to related tasks */
34 wait_queue_head_t waitq; /* sync: sleep on this q */
35 struct rpc_wait_queue * rpc_waitq; /* RPC wait queue we're on */ 34 struct rpc_wait_queue * rpc_waitq; /* RPC wait queue we're on */
36}; 35};
37 36
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 37003970cf2e..5af8800e0ce3 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -185,6 +185,17 @@ xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
185 return vec->iov_len <= PAGE_SIZE; 185 return vec->iov_len <= PAGE_SIZE;
186} 186}
187 187
188static inline struct page *
189svc_take_res_page(struct svc_rqst *rqstp)
190{
191 if (rqstp->rq_arghi <= rqstp->rq_argused)
192 return NULL;
193 rqstp->rq_arghi--;
194 rqstp->rq_respages[rqstp->rq_resused] =
195 rqstp->rq_argpages[rqstp->rq_arghi];
196 return rqstp->rq_respages[rqstp->rq_resused++];
197}
198
188static inline int svc_take_page(struct svc_rqst *rqstp) 199static inline int svc_take_page(struct svc_rqst *rqstp)
189{ 200{
190 if (rqstp->rq_arghi <= rqstp->rq_argused) 201 if (rqstp->rq_arghi <= rqstp->rq_argused)
@@ -240,9 +251,10 @@ struct svc_deferred_req {
240}; 251};
241 252
242/* 253/*
243 * RPC program 254 * List of RPC programs on the same transport endpoint
244 */ 255 */
245struct svc_program { 256struct svc_program {
257 struct svc_program * pg_next; /* other programs (same xprt) */
246 u32 pg_prog; /* program number */ 258 u32 pg_prog; /* program number */
247 unsigned int pg_lovers; /* lowest version */ 259 unsigned int pg_lovers; /* lowest version */
248 unsigned int pg_hivers; /* lowest version */ 260 unsigned int pg_hivers; /* lowest version */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 541dcf838abf..34ec3e8d99b3 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -146,7 +146,8 @@ extern void xdr_shift_buf(struct xdr_buf *, size_t);
146extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *); 146extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
147extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int); 147extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int);
148extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int); 148extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int);
149extern int read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len); 149extern int read_bytes_from_xdr_buf(struct xdr_buf *, int, void *, int);
150extern int write_bytes_to_xdr_buf(struct xdr_buf *, int, void *, int);
150 151
151/* 152/*
152 * Helper structure for copying from an sk_buff. 153 * Helper structure for copying from an sk_buff.
@@ -160,7 +161,7 @@ typedef struct {
160 161
161typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len); 162typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
162 163
163extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int, 164extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
164 skb_reader_t *, skb_read_actor_t); 165 skb_reader_t *, skb_read_actor_t);
165 166
166struct socket; 167struct socket;
@@ -168,6 +169,22 @@ struct sockaddr;
168extern int xdr_sendpages(struct socket *, struct sockaddr *, int, 169extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
169 struct xdr_buf *, unsigned int, int); 170 struct xdr_buf *, unsigned int, int);
170 171
172extern int xdr_encode_word(struct xdr_buf *, int, u32);
173extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
174
175struct xdr_array2_desc;
176typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
177struct xdr_array2_desc {
178 unsigned int elem_size;
179 unsigned int array_len;
180 xdr_xcode_elem_t xcode;
181};
182
183extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
184 struct xdr_array2_desc *desc);
185extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
186 struct xdr_array2_desc *desc);
187
171/* 188/*
172 * Provide some simple tools for XDR buffer overflow-checking etc. 189 * Provide some simple tools for XDR buffer overflow-checking etc.
173 */ 190 */
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 9bcec9b927b9..505e2d4b3d62 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -66,10 +66,10 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
66 u32 flavor = pseudoflavor_to_flavor(pseudoflavor); 66 u32 flavor = pseudoflavor_to_flavor(pseudoflavor);
67 67
68 if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor])) 68 if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor]))
69 return NULL; 69 return ERR_PTR(-EINVAL);
70 auth = ops->create(clnt, pseudoflavor); 70 auth = ops->create(clnt, pseudoflavor);
71 if (!auth) 71 if (IS_ERR(auth))
72 return NULL; 72 return auth;
73 if (clnt->cl_auth) 73 if (clnt->cl_auth)
74 rpcauth_destroy(clnt->cl_auth); 74 rpcauth_destroy(clnt->cl_auth);
75 clnt->cl_auth = auth; 75 clnt->cl_auth = auth;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index a33b627cbef4..2f7b867161d2 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -660,14 +660,16 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
660{ 660{
661 struct gss_auth *gss_auth; 661 struct gss_auth *gss_auth;
662 struct rpc_auth * auth; 662 struct rpc_auth * auth;
663 int err = -ENOMEM; /* XXX? */
663 664
664 dprintk("RPC: creating GSS authenticator for client %p\n",clnt); 665 dprintk("RPC: creating GSS authenticator for client %p\n",clnt);
665 666
666 if (!try_module_get(THIS_MODULE)) 667 if (!try_module_get(THIS_MODULE))
667 return NULL; 668 return ERR_PTR(err);
668 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) 669 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
669 goto out_dec; 670 goto out_dec;
670 gss_auth->client = clnt; 671 gss_auth->client = clnt;
672 err = -EINVAL;
671 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); 673 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
672 if (!gss_auth->mech) { 674 if (!gss_auth->mech) {
673 printk(KERN_WARNING "%s: Pseudoflavor %d not found!", 675 printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
@@ -675,9 +677,8 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
675 goto err_free; 677 goto err_free;
676 } 678 }
677 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); 679 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
678 /* FIXME: Will go away once privacy support is merged in */ 680 if (gss_auth->service == 0)
679 if (gss_auth->service == RPC_GSS_SVC_PRIVACY) 681 goto err_put_mech;
680 gss_auth->service = RPC_GSS_SVC_INTEGRITY;
681 INIT_LIST_HEAD(&gss_auth->upcalls); 682 INIT_LIST_HEAD(&gss_auth->upcalls);
682 spin_lock_init(&gss_auth->lock); 683 spin_lock_init(&gss_auth->lock);
683 auth = &gss_auth->rpc_auth; 684 auth = &gss_auth->rpc_auth;
@@ -687,15 +688,18 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
687 auth->au_flavor = flavor; 688 auth->au_flavor = flavor;
688 atomic_set(&auth->au_count, 1); 689 atomic_set(&auth->au_count, 1);
689 690
690 if (rpcauth_init_credcache(auth, GSS_CRED_EXPIRE) < 0) 691 err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
692 if (err)
691 goto err_put_mech; 693 goto err_put_mech;
692 694
693 snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s", 695 snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
694 clnt->cl_pathname, 696 clnt->cl_pathname,
695 gss_auth->mech->gm_name); 697 gss_auth->mech->gm_name);
696 gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); 698 gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
697 if (IS_ERR(gss_auth->dentry)) 699 if (IS_ERR(gss_auth->dentry)) {
700 err = PTR_ERR(gss_auth->dentry);
698 goto err_put_mech; 701 goto err_put_mech;
702 }
699 703
700 return auth; 704 return auth;
701err_put_mech: 705err_put_mech:
@@ -704,7 +708,7 @@ err_free:
704 kfree(gss_auth); 708 kfree(gss_auth);
705out_dec: 709out_dec:
706 module_put(THIS_MODULE); 710 module_put(THIS_MODULE);
707 return NULL; 711 return ERR_PTR(err);
708} 712}
709 713
710static void 714static void
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 02bc029d46fe..f17e6153b688 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -97,12 +97,13 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
97 * made to sleep too long. 97 * made to sleep too long.
98 */ 98 */
99struct rpc_clnt * 99struct rpc_clnt *
100rpc_create_client(struct rpc_xprt *xprt, char *servname, 100rpc_new_client(struct rpc_xprt *xprt, char *servname,
101 struct rpc_program *program, u32 vers, 101 struct rpc_program *program, u32 vers,
102 rpc_authflavor_t flavor) 102 rpc_authflavor_t flavor)
103{ 103{
104 struct rpc_version *version; 104 struct rpc_version *version;
105 struct rpc_clnt *clnt = NULL; 105 struct rpc_clnt *clnt = NULL;
106 struct rpc_auth *auth;
106 int err; 107 int err;
107 int len; 108 int len;
108 109
@@ -157,10 +158,11 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
157 if (err < 0) 158 if (err < 0)
158 goto out_no_path; 159 goto out_no_path;
159 160
160 err = -ENOMEM; 161 auth = rpcauth_create(flavor, clnt);
161 if (!rpcauth_create(flavor, clnt)) { 162 if (IS_ERR(auth)) {
162 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", 163 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
163 flavor); 164 flavor);
165 err = PTR_ERR(auth);
164 goto out_no_auth; 166 goto out_no_auth;
165 } 167 }
166 168
@@ -178,6 +180,37 @@ out_no_path:
178 kfree(clnt->cl_server); 180 kfree(clnt->cl_server);
179 kfree(clnt); 181 kfree(clnt);
180out_err: 182out_err:
183 xprt_destroy(xprt);
184 return ERR_PTR(err);
185}
186
187/**
188 * Create an RPC client
189 * @xprt - pointer to xprt struct
190 * @servname - name of server
191 * @info - rpc_program
192 * @version - rpc_program version
193 * @authflavor - rpc_auth flavour to use
194 *
195 * Creates an RPC client structure, then pings the server in order to
196 * determine if it is up, and if it supports this program and version.
197 *
198 * This function should never be called by asynchronous tasks such as
199 * the portmapper.
200 */
201struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
202 struct rpc_program *info, u32 version, rpc_authflavor_t authflavor)
203{
204 struct rpc_clnt *clnt;
205 int err;
206
207 clnt = rpc_new_client(xprt, servname, info, version, authflavor);
208 if (IS_ERR(clnt))
209 return clnt;
210 err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
211 if (err == 0)
212 return clnt;
213 rpc_shutdown_client(clnt);
181 return ERR_PTR(err); 214 return ERR_PTR(err);
182} 215}
183 216
@@ -208,6 +241,8 @@ rpc_clone_client(struct rpc_clnt *clnt)
208 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 241 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
209 if (new->cl_auth) 242 if (new->cl_auth)
210 atomic_inc(&new->cl_auth->au_count); 243 atomic_inc(&new->cl_auth->au_count);
244 new->cl_pmap = &new->cl_pmap_default;
245 rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait");
211 return new; 246 return new;
212out_no_clnt: 247out_no_clnt:
213 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 248 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -296,6 +331,44 @@ rpc_release_client(struct rpc_clnt *clnt)
296 rpc_destroy_client(clnt); 331 rpc_destroy_client(clnt);
297} 332}
298 333
334/**
335 * rpc_bind_new_program - bind a new RPC program to an existing client
336 * @old - old rpc_client
337 * @program - rpc program to set
338 * @vers - rpc program version
339 *
340 * Clones the rpc client and sets up a new RPC program. This is mainly
341 * of use for enabling different RPC programs to share the same transport.
342 * The Sun NFSv2/v3 ACL protocol can do this.
343 */
344struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
345 struct rpc_program *program,
346 int vers)
347{
348 struct rpc_clnt *clnt;
349 struct rpc_version *version;
350 int err;
351
352 BUG_ON(vers >= program->nrvers || !program->version[vers]);
353 version = program->version[vers];
354 clnt = rpc_clone_client(old);
355 if (IS_ERR(clnt))
356 goto out;
357 clnt->cl_procinfo = version->procs;
358 clnt->cl_maxproc = version->nrprocs;
359 clnt->cl_protname = program->name;
360 clnt->cl_prog = program->number;
361 clnt->cl_vers = version->number;
362 clnt->cl_stats = program->stats;
363 err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
364 if (err != 0) {
365 rpc_shutdown_client(clnt);
366 clnt = ERR_PTR(err);
367 }
368out:
369 return clnt;
370}
371
299/* 372/*
300 * Default callback for async RPC calls 373 * Default callback for async RPC calls
301 */ 374 */
@@ -305,38 +378,41 @@ rpc_default_callback(struct rpc_task *task)
305} 378}
306 379
307/* 380/*
308 * Export the signal mask handling for aysnchronous code that 381 * Export the signal mask handling for synchronous code that
309 * sleeps on RPC calls 382 * sleeps on RPC calls
310 */ 383 */
384#define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL))
311 385
386static void rpc_save_sigmask(sigset_t *oldset, int intr)
387{
388 unsigned long sigallow = 0;
389 sigset_t sigmask;
390
391 /* Block all signals except those listed in sigallow */
392 if (intr)
393 sigallow |= RPC_INTR_SIGNALS;
394 siginitsetinv(&sigmask, sigallow);
395 sigprocmask(SIG_BLOCK, &sigmask, oldset);
396}
397
398static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset)
399{
400 rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task));
401}
402
403static inline void rpc_restore_sigmask(sigset_t *oldset)
404{
405 sigprocmask(SIG_SETMASK, oldset, NULL);
406}
407
312void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset) 408void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset)
313{ 409{
314 unsigned long sigallow = sigmask(SIGKILL); 410 rpc_save_sigmask(oldset, clnt->cl_intr);
315 unsigned long irqflags;
316
317 /* Turn off various signals */
318 if (clnt->cl_intr) {
319 struct k_sigaction *action = current->sighand->action;
320 if (action[SIGINT-1].sa.sa_handler == SIG_DFL)
321 sigallow |= sigmask(SIGINT);
322 if (action[SIGQUIT-1].sa.sa_handler == SIG_DFL)
323 sigallow |= sigmask(SIGQUIT);
324 }
325 spin_lock_irqsave(&current->sighand->siglock, irqflags);
326 *oldset = current->blocked;
327 siginitsetinv(&current->blocked, sigallow & ~oldset->sig[0]);
328 recalc_sigpending();
329 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
330} 411}
331 412
332void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) 413void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
333{ 414{
334 unsigned long irqflags; 415 rpc_restore_sigmask(oldset);
335
336 spin_lock_irqsave(&current->sighand->siglock, irqflags);
337 current->blocked = *oldset;
338 recalc_sigpending();
339 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
340} 416}
341 417
342/* 418/*
@@ -354,26 +430,26 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
354 430
355 BUG_ON(flags & RPC_TASK_ASYNC); 431 BUG_ON(flags & RPC_TASK_ASYNC);
356 432
357 rpc_clnt_sigmask(clnt, &oldset);
358
359 status = -ENOMEM; 433 status = -ENOMEM;
360 task = rpc_new_task(clnt, NULL, flags); 434 task = rpc_new_task(clnt, NULL, flags);
361 if (task == NULL) 435 if (task == NULL)
362 goto out; 436 goto out;
363 437
438 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
439 rpc_task_sigmask(task, &oldset);
440
364 rpc_call_setup(task, msg, 0); 441 rpc_call_setup(task, msg, 0);
365 442
366 /* Set up the call info struct and execute the task */ 443 /* Set up the call info struct and execute the task */
367 if (task->tk_status == 0) 444 if (task->tk_status == 0) {
368 status = rpc_execute(task); 445 status = rpc_execute(task);
369 else { 446 } else {
370 status = task->tk_status; 447 status = task->tk_status;
371 rpc_release_task(task); 448 rpc_release_task(task);
372 } 449 }
373 450
451 rpc_restore_sigmask(&oldset);
374out: 452out:
375 rpc_clnt_sigunmask(clnt, &oldset);
376
377 return status; 453 return status;
378} 454}
379 455
@@ -394,8 +470,6 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
394 470
395 flags |= RPC_TASK_ASYNC; 471 flags |= RPC_TASK_ASYNC;
396 472
397 rpc_clnt_sigmask(clnt, &oldset);
398
399 /* Create/initialize a new RPC task */ 473 /* Create/initialize a new RPC task */
400 if (!callback) 474 if (!callback)
401 callback = rpc_default_callback; 475 callback = rpc_default_callback;
@@ -404,6 +478,9 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
404 goto out; 478 goto out;
405 task->tk_calldata = data; 479 task->tk_calldata = data;
406 480
481 /* Mask signals on GSS_AUTH upcalls */
482 rpc_task_sigmask(task, &oldset);
483
407 rpc_call_setup(task, msg, 0); 484 rpc_call_setup(task, msg, 0);
408 485
409 /* Set up the call info struct and execute the task */ 486 /* Set up the call info struct and execute the task */
@@ -413,9 +490,8 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
413 else 490 else
414 rpc_release_task(task); 491 rpc_release_task(task);
415 492
493 rpc_restore_sigmask(&oldset);
416out: 494out:
417 rpc_clnt_sigunmask(clnt, &oldset);
418
419 return status; 495 return status;
420} 496}
421 497
@@ -593,7 +669,7 @@ call_allocate(struct rpc_task *task)
593 return; 669 return;
594 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 670 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task);
595 671
596 if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) { 672 if (RPC_IS_ASYNC(task) || !signalled()) {
597 xprt_release(task); 673 xprt_release(task);
598 task->tk_action = call_reserve; 674 task->tk_action = call_reserve;
599 rpc_delay(task, HZ>>4); 675 rpc_delay(task, HZ>>4);
@@ -957,7 +1033,9 @@ call_header(struct rpc_task *task)
957 *p++ = htonl(clnt->cl_prog); /* program number */ 1033 *p++ = htonl(clnt->cl_prog); /* program number */
958 *p++ = htonl(clnt->cl_vers); /* program version */ 1034 *p++ = htonl(clnt->cl_vers); /* program version */
959 *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ 1035 *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */
960 return rpcauth_marshcred(task, p); 1036 p = rpcauth_marshcred(task, p);
1037 req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
1038 return p;
961} 1039}
962 1040
963/* 1041/*
@@ -986,10 +1064,11 @@ call_verify(struct rpc_task *task)
986 case RPC_AUTH_ERROR: 1064 case RPC_AUTH_ERROR:
987 break; 1065 break;
988 case RPC_MISMATCH: 1066 case RPC_MISMATCH:
989 printk(KERN_WARNING "%s: RPC call version mismatch!\n", __FUNCTION__); 1067 dprintk("%s: RPC call version mismatch!\n", __FUNCTION__);
990 goto out_eio; 1068 error = -EPROTONOSUPPORT;
1069 goto out_err;
991 default: 1070 default:
992 printk(KERN_WARNING "%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n); 1071 dprintk("%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n);
993 goto out_eio; 1072 goto out_eio;
994 } 1073 }
995 if (--len < 0) 1074 if (--len < 0)
@@ -1040,23 +1119,26 @@ call_verify(struct rpc_task *task)
1040 case RPC_SUCCESS: 1119 case RPC_SUCCESS:
1041 return p; 1120 return p;
1042 case RPC_PROG_UNAVAIL: 1121 case RPC_PROG_UNAVAIL:
1043 printk(KERN_WARNING "RPC: call_verify: program %u is unsupported by server %s\n", 1122 dprintk("RPC: call_verify: program %u is unsupported by server %s\n",
1044 (unsigned int)task->tk_client->cl_prog, 1123 (unsigned int)task->tk_client->cl_prog,
1045 task->tk_client->cl_server); 1124 task->tk_client->cl_server);
1046 goto out_eio; 1125 error = -EPFNOSUPPORT;
1126 goto out_err;
1047 case RPC_PROG_MISMATCH: 1127 case RPC_PROG_MISMATCH:
1048 printk(KERN_WARNING "RPC: call_verify: program %u, version %u unsupported by server %s\n", 1128 dprintk("RPC: call_verify: program %u, version %u unsupported by server %s\n",
1049 (unsigned int)task->tk_client->cl_prog, 1129 (unsigned int)task->tk_client->cl_prog,
1050 (unsigned int)task->tk_client->cl_vers, 1130 (unsigned int)task->tk_client->cl_vers,
1051 task->tk_client->cl_server); 1131 task->tk_client->cl_server);
1052 goto out_eio; 1132 error = -EPROTONOSUPPORT;
1133 goto out_err;
1053 case RPC_PROC_UNAVAIL: 1134 case RPC_PROC_UNAVAIL:
1054 printk(KERN_WARNING "RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n", 1135 dprintk("RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n",
1055 task->tk_msg.rpc_proc, 1136 task->tk_msg.rpc_proc,
1056 task->tk_client->cl_prog, 1137 task->tk_client->cl_prog,
1057 task->tk_client->cl_vers, 1138 task->tk_client->cl_vers,
1058 task->tk_client->cl_server); 1139 task->tk_client->cl_server);
1059 goto out_eio; 1140 error = -EOPNOTSUPP;
1141 goto out_err;
1060 case RPC_GARBAGE_ARGS: 1142 case RPC_GARBAGE_ARGS:
1061 dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__); 1143 dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__);
1062 break; /* retry */ 1144 break; /* retry */
@@ -1069,7 +1151,7 @@ out_retry:
1069 task->tk_client->cl_stats->rpcgarbage++; 1151 task->tk_client->cl_stats->rpcgarbage++;
1070 if (task->tk_garb_retry) { 1152 if (task->tk_garb_retry) {
1071 task->tk_garb_retry--; 1153 task->tk_garb_retry--;
1072 dprintk(KERN_WARNING "RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); 1154 dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
1073 task->tk_action = call_bind; 1155 task->tk_action = call_bind;
1074 return NULL; 1156 return NULL;
1075 } 1157 }
@@ -1083,3 +1165,30 @@ out_overflow:
1083 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); 1165 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
1084 goto out_retry; 1166 goto out_retry;
1085} 1167}
1168
1169static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
1170{
1171 return 0;
1172}
1173
1174static int rpcproc_decode_null(void *rqstp, u32 *data, void *obj)
1175{
1176 return 0;
1177}
1178
1179static struct rpc_procinfo rpcproc_null = {
1180 .p_encode = rpcproc_encode_null,
1181 .p_decode = rpcproc_decode_null,
1182};
1183
1184int rpc_ping(struct rpc_clnt *clnt, int flags)
1185{
1186 struct rpc_message msg = {
1187 .rpc_proc = &rpcproc_null,
1188 };
1189 int err;
1190 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
1191 err = rpc_call_sync(clnt, &msg, flags);
1192 put_rpccred(msg.rpc_cred);
1193 return err;
1194}
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index d0b1d2c34a4d..4e81f2766923 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -53,6 +53,9 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
53 task->tk_pid, clnt->cl_server, 53 task->tk_pid, clnt->cl_server,
54 map->pm_prog, map->pm_vers, map->pm_prot); 54 map->pm_prog, map->pm_vers, map->pm_prot);
55 55
56 /* Autobind on cloned rpc clients is discouraged */
57 BUG_ON(clnt->cl_parent != clnt);
58
56 spin_lock(&pmap_lock); 59 spin_lock(&pmap_lock);
57 if (map->pm_binding) { 60 if (map->pm_binding) {
58 rpc_sleep_on(&map->pm_bindwait, task, NULL, NULL); 61 rpc_sleep_on(&map->pm_bindwait, task, NULL, NULL);
@@ -207,12 +210,10 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto)
207 xprt->addr.sin_port = htons(RPC_PMAP_PORT); 210 xprt->addr.sin_port = htons(RPC_PMAP_PORT);
208 211
209 /* printk("pmap: create clnt\n"); */ 212 /* printk("pmap: create clnt\n"); */
210 clnt = rpc_create_client(xprt, hostname, 213 clnt = rpc_new_client(xprt, hostname,
211 &pmap_program, RPC_PMAP_VERSION, 214 &pmap_program, RPC_PMAP_VERSION,
212 RPC_AUTH_UNIX); 215 RPC_AUTH_UNIX);
213 if (IS_ERR(clnt)) { 216 if (!IS_ERR(clnt)) {
214 xprt_destroy(xprt);
215 } else {
216 clnt->cl_softrtry = 1; 217 clnt->cl_softrtry = 1;
217 clnt->cl_chatty = 1; 218 clnt->cl_chatty = 1;
218 clnt->cl_oneshot = 1; 219 clnt->cl_oneshot = 1;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index c06614d0e31d..2d9eb7fbd521 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -290,7 +290,7 @@ static void rpc_make_runnable(struct rpc_task *task)
290 return; 290 return;
291 } 291 }
292 } else 292 } else
293 wake_up(&task->u.tk_wait.waitq); 293 wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED);
294} 294}
295 295
296/* 296/*
@@ -555,6 +555,38 @@ __rpc_atrun(struct rpc_task *task)
555} 555}
556 556
557/* 557/*
558 * Helper that calls task->tk_exit if it exists and then returns
559 * true if we should exit __rpc_execute.
560 */
561static inline int __rpc_do_exit(struct rpc_task *task)
562{
563 if (task->tk_exit != NULL) {
564 lock_kernel();
565 task->tk_exit(task);
566 unlock_kernel();
567 /* If tk_action is non-null, we should restart the call */
568 if (task->tk_action != NULL) {
569 if (!RPC_ASSASSINATED(task)) {
570 /* Release RPC slot and buffer memory */
571 xprt_release(task);
572 rpc_free(task);
573 return 0;
574 }
575 printk(KERN_ERR "RPC: dead task tried to walk away.\n");
576 }
577 }
578 return 1;
579}
580
581static int rpc_wait_bit_interruptible(void *word)
582{
583 if (signal_pending(current))
584 return -ERESTARTSYS;
585 schedule();
586 return 0;
587}
588
589/*
558 * This is the RPC `scheduler' (or rather, the finite state machine). 590 * This is the RPC `scheduler' (or rather, the finite state machine).
559 */ 591 */
560static int __rpc_execute(struct rpc_task *task) 592static int __rpc_execute(struct rpc_task *task)
@@ -566,8 +598,7 @@ static int __rpc_execute(struct rpc_task *task)
566 598
567 BUG_ON(RPC_IS_QUEUED(task)); 599 BUG_ON(RPC_IS_QUEUED(task));
568 600
569 restarted: 601 for (;;) {
570 while (1) {
571 /* 602 /*
572 * Garbage collection of pending timers... 603 * Garbage collection of pending timers...
573 */ 604 */
@@ -600,11 +631,12 @@ static int __rpc_execute(struct rpc_task *task)
600 * by someone else. 631 * by someone else.
601 */ 632 */
602 if (!RPC_IS_QUEUED(task)) { 633 if (!RPC_IS_QUEUED(task)) {
603 if (!task->tk_action) 634 if (task->tk_action != NULL) {
635 lock_kernel();
636 task->tk_action(task);
637 unlock_kernel();
638 } else if (__rpc_do_exit(task))
604 break; 639 break;
605 lock_kernel();
606 task->tk_action(task);
607 unlock_kernel();
608 } 640 }
609 641
610 /* 642 /*
@@ -624,44 +656,26 @@ static int __rpc_execute(struct rpc_task *task)
624 656
625 /* sync task: sleep here */ 657 /* sync task: sleep here */
626 dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid); 658 dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid);
627 if (RPC_TASK_UNINTERRUPTIBLE(task)) { 659 /* Note: Caller should be using rpc_clnt_sigmask() */
628 __wait_event(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task)); 660 status = out_of_line_wait_on_bit(&task->tk_runstate,
629 } else { 661 RPC_TASK_QUEUED, rpc_wait_bit_interruptible,
630 __wait_event_interruptible(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task), status); 662 TASK_INTERRUPTIBLE);
663 if (status == -ERESTARTSYS) {
631 /* 664 /*
632 * When a sync task receives a signal, it exits with 665 * When a sync task receives a signal, it exits with
633 * -ERESTARTSYS. In order to catch any callbacks that 666 * -ERESTARTSYS. In order to catch any callbacks that
634 * clean up after sleeping on some queue, we don't 667 * clean up after sleeping on some queue, we don't
635 * break the loop here, but go around once more. 668 * break the loop here, but go around once more.
636 */ 669 */
637 if (status == -ERESTARTSYS) { 670 dprintk("RPC: %4d got signal\n", task->tk_pid);
638 dprintk("RPC: %4d got signal\n", task->tk_pid); 671 task->tk_flags |= RPC_TASK_KILLED;
639 task->tk_flags |= RPC_TASK_KILLED; 672 rpc_exit(task, -ERESTARTSYS);
640 rpc_exit(task, -ERESTARTSYS); 673 rpc_wake_up_task(task);
641 rpc_wake_up_task(task);
642 }
643 } 674 }
644 rpc_set_running(task); 675 rpc_set_running(task);
645 dprintk("RPC: %4d sync task resuming\n", task->tk_pid); 676 dprintk("RPC: %4d sync task resuming\n", task->tk_pid);
646 } 677 }
647 678
648 if (task->tk_exit) {
649 lock_kernel();
650 task->tk_exit(task);
651 unlock_kernel();
652 /* If tk_action is non-null, the user wants us to restart */
653 if (task->tk_action) {
654 if (!RPC_ASSASSINATED(task)) {
655 /* Release RPC slot and buffer memory */
656 if (task->tk_rqstp)
657 xprt_release(task);
658 rpc_free(task);
659 goto restarted;
660 }
661 printk(KERN_ERR "RPC: dead task tries to walk away.\n");
662 }
663 }
664
665 dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status); 679 dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status);
666 status = task->tk_status; 680 status = task->tk_status;
667 681
@@ -759,8 +773,6 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call
759 773
760 /* Initialize workqueue for async tasks */ 774 /* Initialize workqueue for async tasks */
761 task->tk_workqueue = rpciod_workqueue; 775 task->tk_workqueue = rpciod_workqueue;
762 if (!RPC_IS_ASYNC(task))
763 init_waitqueue_head(&task->u.tk_wait.waitq);
764 776
765 if (clnt) { 777 if (clnt) {
766 atomic_inc(&clnt->cl_users); 778 atomic_inc(&clnt->cl_users);
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index d4f26bf9e732..32e8acbc60fe 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -42,6 +42,7 @@ EXPORT_SYMBOL(rpc_release_task);
42/* RPC client functions */ 42/* RPC client functions */
43EXPORT_SYMBOL(rpc_create_client); 43EXPORT_SYMBOL(rpc_create_client);
44EXPORT_SYMBOL(rpc_clone_client); 44EXPORT_SYMBOL(rpc_clone_client);
45EXPORT_SYMBOL(rpc_bind_new_program);
45EXPORT_SYMBOL(rpc_destroy_client); 46EXPORT_SYMBOL(rpc_destroy_client);
46EXPORT_SYMBOL(rpc_shutdown_client); 47EXPORT_SYMBOL(rpc_shutdown_client);
47EXPORT_SYMBOL(rpc_release_client); 48EXPORT_SYMBOL(rpc_release_client);
@@ -61,7 +62,6 @@ EXPORT_SYMBOL(rpc_mkpipe);
61 62
62/* Client transport */ 63/* Client transport */
63EXPORT_SYMBOL(xprt_create_proto); 64EXPORT_SYMBOL(xprt_create_proto);
64EXPORT_SYMBOL(xprt_destroy);
65EXPORT_SYMBOL(xprt_set_timeout); 65EXPORT_SYMBOL(xprt_set_timeout);
66EXPORT_SYMBOL(xprt_udp_slot_table_entries); 66EXPORT_SYMBOL(xprt_udp_slot_table_entries);
67EXPORT_SYMBOL(xprt_tcp_slot_table_entries); 67EXPORT_SYMBOL(xprt_tcp_slot_table_entries);
@@ -129,6 +129,10 @@ EXPORT_SYMBOL(xdr_encode_netobj);
129EXPORT_SYMBOL(xdr_encode_pages); 129EXPORT_SYMBOL(xdr_encode_pages);
130EXPORT_SYMBOL(xdr_inline_pages); 130EXPORT_SYMBOL(xdr_inline_pages);
131EXPORT_SYMBOL(xdr_shift_buf); 131EXPORT_SYMBOL(xdr_shift_buf);
132EXPORT_SYMBOL(xdr_encode_word);
133EXPORT_SYMBOL(xdr_decode_word);
134EXPORT_SYMBOL(xdr_encode_array2);
135EXPORT_SYMBOL(xdr_decode_array2);
132EXPORT_SYMBOL(xdr_buf_from_iov); 136EXPORT_SYMBOL(xdr_buf_from_iov);
133EXPORT_SYMBOL(xdr_buf_subsegment); 137EXPORT_SYMBOL(xdr_buf_subsegment);
134EXPORT_SYMBOL(xdr_buf_read_netobj); 138EXPORT_SYMBOL(xdr_buf_read_netobj);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index bb2d99f33315..e9bd91265f70 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -35,20 +35,24 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
35 if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL))) 35 if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
36 return NULL; 36 return NULL;
37 memset(serv, 0, sizeof(*serv)); 37 memset(serv, 0, sizeof(*serv));
38 serv->sv_name = prog->pg_name;
38 serv->sv_program = prog; 39 serv->sv_program = prog;
39 serv->sv_nrthreads = 1; 40 serv->sv_nrthreads = 1;
40 serv->sv_stats = prog->pg_stats; 41 serv->sv_stats = prog->pg_stats;
41 serv->sv_bufsz = bufsize? bufsize : 4096; 42 serv->sv_bufsz = bufsize? bufsize : 4096;
42 prog->pg_lovers = prog->pg_nvers-1;
43 xdrsize = 0; 43 xdrsize = 0;
44 for (vers=0; vers<prog->pg_nvers ; vers++) 44 while (prog) {
45 if (prog->pg_vers[vers]) { 45 prog->pg_lovers = prog->pg_nvers-1;
46 prog->pg_hivers = vers; 46 for (vers=0; vers<prog->pg_nvers ; vers++)
47 if (prog->pg_lovers > vers) 47 if (prog->pg_vers[vers]) {
48 prog->pg_lovers = vers; 48 prog->pg_hivers = vers;
49 if (prog->pg_vers[vers]->vs_xdrsize > xdrsize) 49 if (prog->pg_lovers > vers)
50 xdrsize = prog->pg_vers[vers]->vs_xdrsize; 50 prog->pg_lovers = vers;
51 } 51 if (prog->pg_vers[vers]->vs_xdrsize > xdrsize)
52 xdrsize = prog->pg_vers[vers]->vs_xdrsize;
53 }
54 prog = prog->pg_next;
55 }
52 serv->sv_xdrsize = xdrsize; 56 serv->sv_xdrsize = xdrsize;
53 INIT_LIST_HEAD(&serv->sv_threads); 57 INIT_LIST_HEAD(&serv->sv_threads);
54 INIT_LIST_HEAD(&serv->sv_sockets); 58 INIT_LIST_HEAD(&serv->sv_sockets);
@@ -56,8 +60,6 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
56 INIT_LIST_HEAD(&serv->sv_permsocks); 60 INIT_LIST_HEAD(&serv->sv_permsocks);
57 spin_lock_init(&serv->sv_lock); 61 spin_lock_init(&serv->sv_lock);
58 62
59 serv->sv_name = prog->pg_name;
60
61 /* Remove any stale portmap registrations */ 63 /* Remove any stale portmap registrations */
62 svc_register(serv, 0, 0); 64 svc_register(serv, 0, 0);
63 65
@@ -281,6 +283,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
281 rqstp->rq_res.len = 0; 283 rqstp->rq_res.len = 0;
282 rqstp->rq_res.page_base = 0; 284 rqstp->rq_res.page_base = 0;
283 rqstp->rq_res.page_len = 0; 285 rqstp->rq_res.page_len = 0;
286 rqstp->rq_res.buflen = PAGE_SIZE;
284 rqstp->rq_res.tail[0].iov_len = 0; 287 rqstp->rq_res.tail[0].iov_len = 0;
285 /* tcp needs a space for the record length... */ 288 /* tcp needs a space for the record length... */
286 if (rqstp->rq_prot == IPPROTO_TCP) 289 if (rqstp->rq_prot == IPPROTO_TCP)
@@ -338,7 +341,10 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
338 goto sendit; 341 goto sendit;
339 } 342 }
340 343
341 if (prog != progp->pg_prog) 344 for (progp = serv->sv_program; progp; progp = progp->pg_next)
345 if (prog == progp->pg_prog)
346 break;
347 if (progp == NULL)
342 goto err_bad_prog; 348 goto err_bad_prog;
343 349
344 if (vers >= progp->pg_nvers || 350 if (vers >= progp->pg_nvers ||
@@ -451,11 +457,7 @@ err_bad_auth:
451 goto sendit; 457 goto sendit;
452 458
453err_bad_prog: 459err_bad_prog:
454#ifdef RPC_PARANOIA 460 dprintk("svc: unknown program %d\n", prog);
455 if (prog != 100227 || progp->pg_prog != 100003)
456 printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
457 /* else it is just a Solaris client seeing if ACLs are supported */
458#endif
459 serv->sv_stats->rpcbadfmt++; 461 serv->sv_stats->rpcbadfmt++;
460 svc_putu32(resv, rpc_prog_unavail); 462 svc_putu32(resv, rpc_prog_unavail);
461 goto sendit; 463 goto sendit;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 67b9f035ba86..8a4d9c106af1 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -176,21 +176,23 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset,
176 xdr->buflen += len; 176 xdr->buflen += len;
177} 177}
178 178
179void 179ssize_t
180xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, 180xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
181 skb_reader_t *desc, 181 skb_reader_t *desc,
182 skb_read_actor_t copy_actor) 182 skb_read_actor_t copy_actor)
183{ 183{
184 struct page **ppage = xdr->pages; 184 struct page **ppage = xdr->pages;
185 unsigned int len, pglen = xdr->page_len; 185 unsigned int len, pglen = xdr->page_len;
186 ssize_t copied = 0;
186 int ret; 187 int ret;
187 188
188 len = xdr->head[0].iov_len; 189 len = xdr->head[0].iov_len;
189 if (base < len) { 190 if (base < len) {
190 len -= base; 191 len -= base;
191 ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len); 192 ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
193 copied += ret;
192 if (ret != len || !desc->count) 194 if (ret != len || !desc->count)
193 return; 195 goto out;
194 base = 0; 196 base = 0;
195 } else 197 } else
196 base -= len; 198 base -= len;
@@ -210,6 +212,17 @@ xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
210 do { 212 do {
211 char *kaddr; 213 char *kaddr;
212 214
215 /* ACL likes to be lazy in allocating pages - ACLs
216 * are small by default but can get huge. */
217 if (unlikely(*ppage == NULL)) {
218 *ppage = alloc_page(GFP_ATOMIC);
219 if (unlikely(*ppage == NULL)) {
220 if (copied == 0)
221 copied = -ENOMEM;
222 goto out;
223 }
224 }
225
213 len = PAGE_CACHE_SIZE; 226 len = PAGE_CACHE_SIZE;
214 kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA); 227 kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
215 if (base) { 228 if (base) {
@@ -225,14 +238,17 @@ xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
225 } 238 }
226 flush_dcache_page(*ppage); 239 flush_dcache_page(*ppage);
227 kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA); 240 kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
241 copied += ret;
228 if (ret != len || !desc->count) 242 if (ret != len || !desc->count)
229 return; 243 goto out;
230 ppage++; 244 ppage++;
231 } while ((pglen -= len) != 0); 245 } while ((pglen -= len) != 0);
232copy_tail: 246copy_tail:
233 len = xdr->tail[0].iov_len; 247 len = xdr->tail[0].iov_len;
234 if (base < len) 248 if (base < len)
235 copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base); 249 copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
250out:
251 return copied;
236} 252}
237 253
238 254
@@ -616,12 +632,24 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len)
616void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p) 632void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
617{ 633{
618 struct kvec *iov = buf->head; 634 struct kvec *iov = buf->head;
635 int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
619 636
637 BUG_ON(scratch_len < 0);
620 xdr->buf = buf; 638 xdr->buf = buf;
621 xdr->iov = iov; 639 xdr->iov = iov;
622 xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len); 640 xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
623 buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base; 641 xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
624 xdr->p = p; 642 BUG_ON(iov->iov_len > scratch_len);
643
644 if (p != xdr->p && p != NULL) {
645 size_t len;
646
647 BUG_ON(p < xdr->p || p > xdr->end);
648 len = (char *)p - (char *)xdr->p;
649 xdr->p = p;
650 buf->len += len;
651 iov->iov_len += len;
652 }
625} 653}
626EXPORT_SYMBOL(xdr_init_encode); 654EXPORT_SYMBOL(xdr_init_encode);
627 655
@@ -859,8 +887,34 @@ out:
859 return status; 887 return status;
860} 888}
861 889
862static int 890/* obj is assumed to point to allocated memory of size at least len: */
863read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj) 891int
892write_bytes_to_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len)
893{
894 struct xdr_buf subbuf;
895 int this_len;
896 int status;
897
898 status = xdr_buf_subsegment(buf, &subbuf, base, len);
899 if (status)
900 goto out;
901 this_len = min(len, (int)subbuf.head[0].iov_len);
902 memcpy(subbuf.head[0].iov_base, obj, this_len);
903 len -= this_len;
904 obj += this_len;
905 this_len = min(len, (int)subbuf.page_len);
906 if (this_len)
907 _copy_to_pages(subbuf.pages, subbuf.page_base, obj, this_len);
908 len -= this_len;
909 obj += this_len;
910 this_len = min(len, (int)subbuf.tail[0].iov_len);
911 memcpy(subbuf.tail[0].iov_base, obj, this_len);
912out:
913 return status;
914}
915
916int
917xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
864{ 918{
865 u32 raw; 919 u32 raw;
866 int status; 920 int status;
@@ -872,6 +926,14 @@ read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
872 return 0; 926 return 0;
873} 927}
874 928
929int
930xdr_encode_word(struct xdr_buf *buf, int base, u32 obj)
931{
932 u32 raw = htonl(obj);
933
934 return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
935}
936
875/* If the netobj starting offset bytes from the start of xdr_buf is contained 937/* If the netobj starting offset bytes from the start of xdr_buf is contained
876 * entirely in the head or the tail, set object to point to it; otherwise 938 * entirely in the head or the tail, set object to point to it; otherwise
877 * try to find space for it at the end of the tail, copy it there, and 939 * try to find space for it at the end of the tail, copy it there, and
@@ -882,7 +944,7 @@ xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, int offset)
882 u32 tail_offset = buf->head[0].iov_len + buf->page_len; 944 u32 tail_offset = buf->head[0].iov_len + buf->page_len;
883 u32 obj_end_offset; 945 u32 obj_end_offset;
884 946
885 if (read_u32_from_xdr_buf(buf, offset, &obj->len)) 947 if (xdr_decode_word(buf, offset, &obj->len))
886 goto out; 948 goto out;
887 obj_end_offset = offset + 4 + obj->len; 949 obj_end_offset = offset + 4 + obj->len;
888 950
@@ -915,3 +977,219 @@ xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, int offset)
915out: 977out:
916 return -1; 978 return -1;
917} 979}
980
981/* Returns 0 on success, or else a negative error code. */
982static int
983xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
984 struct xdr_array2_desc *desc, int encode)
985{
986 char *elem = NULL, *c;
987 unsigned int copied = 0, todo, avail_here;
988 struct page **ppages = NULL;
989 int err;
990
991 if (encode) {
992 if (xdr_encode_word(buf, base, desc->array_len) != 0)
993 return -EINVAL;
994 } else {
995 if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
996 (unsigned long) base + 4 + desc->array_len *
997 desc->elem_size > buf->len)
998 return -EINVAL;
999 }
1000 base += 4;
1001
1002 if (!desc->xcode)
1003 return 0;
1004
1005 todo = desc->array_len * desc->elem_size;
1006
1007 /* process head */
1008 if (todo && base < buf->head->iov_len) {
1009 c = buf->head->iov_base + base;
1010 avail_here = min_t(unsigned int, todo,
1011 buf->head->iov_len - base);
1012 todo -= avail_here;
1013
1014 while (avail_here >= desc->elem_size) {
1015 err = desc->xcode(desc, c);
1016 if (err)
1017 goto out;
1018 c += desc->elem_size;
1019 avail_here -= desc->elem_size;
1020 }
1021 if (avail_here) {
1022 if (!elem) {
1023 elem = kmalloc(desc->elem_size, GFP_KERNEL);
1024 err = -ENOMEM;
1025 if (!elem)
1026 goto out;
1027 }
1028 if (encode) {
1029 err = desc->xcode(desc, elem);
1030 if (err)
1031 goto out;
1032 memcpy(c, elem, avail_here);
1033 } else
1034 memcpy(elem, c, avail_here);
1035 copied = avail_here;
1036 }
1037 base = buf->head->iov_len; /* align to start of pages */
1038 }
1039
1040 /* process pages array */
1041 base -= buf->head->iov_len;
1042 if (todo && base < buf->page_len) {
1043 unsigned int avail_page;
1044
1045 avail_here = min(todo, buf->page_len - base);
1046 todo -= avail_here;
1047
1048 base += buf->page_base;
1049 ppages = buf->pages + (base >> PAGE_CACHE_SHIFT);
1050 base &= ~PAGE_CACHE_MASK;
1051 avail_page = min_t(unsigned int, PAGE_CACHE_SIZE - base,
1052 avail_here);
1053 c = kmap(*ppages) + base;
1054
1055 while (avail_here) {
1056 avail_here -= avail_page;
1057 if (copied || avail_page < desc->elem_size) {
1058 unsigned int l = min(avail_page,
1059 desc->elem_size - copied);
1060 if (!elem) {
1061 elem = kmalloc(desc->elem_size,
1062 GFP_KERNEL);
1063 err = -ENOMEM;
1064 if (!elem)
1065 goto out;
1066 }
1067 if (encode) {
1068 if (!copied) {
1069 err = desc->xcode(desc, elem);
1070 if (err)
1071 goto out;
1072 }
1073 memcpy(c, elem + copied, l);
1074 copied += l;
1075 if (copied == desc->elem_size)
1076 copied = 0;
1077 } else {
1078 memcpy(elem + copied, c, l);
1079 copied += l;
1080 if (copied == desc->elem_size) {
1081 err = desc->xcode(desc, elem);
1082 if (err)
1083 goto out;
1084 copied = 0;
1085 }
1086 }
1087 avail_page -= l;
1088 c += l;
1089 }
1090 while (avail_page >= desc->elem_size) {
1091 err = desc->xcode(desc, c);
1092 if (err)
1093 goto out;
1094 c += desc->elem_size;
1095 avail_page -= desc->elem_size;
1096 }
1097 if (avail_page) {
1098 unsigned int l = min(avail_page,
1099 desc->elem_size - copied);
1100 if (!elem) {
1101 elem = kmalloc(desc->elem_size,
1102 GFP_KERNEL);
1103 err = -ENOMEM;
1104 if (!elem)
1105 goto out;
1106 }
1107 if (encode) {
1108 if (!copied) {
1109 err = desc->xcode(desc, elem);
1110 if (err)
1111 goto out;
1112 }
1113 memcpy(c, elem + copied, l);
1114 copied += l;
1115 if (copied == desc->elem_size)
1116 copied = 0;
1117 } else {
1118 memcpy(elem + copied, c, l);
1119 copied += l;
1120 if (copied == desc->elem_size) {
1121 err = desc->xcode(desc, elem);
1122 if (err)
1123 goto out;
1124 copied = 0;
1125 }
1126 }
1127 }
1128 if (avail_here) {
1129 kunmap(*ppages);
1130 ppages++;
1131 c = kmap(*ppages);
1132 }
1133
1134 avail_page = min(avail_here,
1135 (unsigned int) PAGE_CACHE_SIZE);
1136 }
1137 base = buf->page_len; /* align to start of tail */
1138 }
1139
1140 /* process tail */
1141 base -= buf->page_len;
1142 if (todo) {
1143 c = buf->tail->iov_base + base;
1144 if (copied) {
1145 unsigned int l = desc->elem_size - copied;
1146
1147 if (encode)
1148 memcpy(c, elem + copied, l);
1149 else {
1150 memcpy(elem + copied, c, l);
1151 err = desc->xcode(desc, elem);
1152 if (err)
1153 goto out;
1154 }
1155 todo -= l;
1156 c += l;
1157 }
1158 while (todo) {
1159 err = desc->xcode(desc, c);
1160 if (err)
1161 goto out;
1162 c += desc->elem_size;
1163 todo -= desc->elem_size;
1164 }
1165 }
1166 err = 0;
1167
1168out:
1169 if (elem)
1170 kfree(elem);
1171 if (ppages)
1172 kunmap(*ppages);
1173 return err;
1174}
1175
1176int
1177xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
1178 struct xdr_array2_desc *desc)
1179{
1180 if (base >= buf->len)
1181 return -EINVAL;
1182
1183 return xdr_xcode_array2(buf, base, desc, 0);
1184}
1185
1186int
1187xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
1188 struct xdr_array2_desc *desc)
1189{
1190 if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
1191 buf->head->iov_len + buf->page_len + buf->tail->iov_len)
1192 return -EINVAL;
1193
1194 return xdr_xcode_array2(buf, base, desc, 1);
1195}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c74a6bb94074..eca92405948f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -569,8 +569,11 @@ void xprt_connect(struct rpc_task *task)
569 if (xprt->sock != NULL) 569 if (xprt->sock != NULL)
570 schedule_delayed_work(&xprt->sock_connect, 570 schedule_delayed_work(&xprt->sock_connect,
571 RPC_REESTABLISH_TIMEOUT); 571 RPC_REESTABLISH_TIMEOUT);
572 else 572 else {
573 schedule_work(&xprt->sock_connect); 573 schedule_work(&xprt->sock_connect);
574 if (!RPC_IS_ASYNC(task))
575 flush_scheduled_work();
576 }
574 } 577 }
575 return; 578 return;
576 out_write: 579 out_write:
@@ -725,7 +728,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
725 goto no_checksum; 728 goto no_checksum;
726 729
727 desc.csum = csum_partial(skb->data, desc.offset, skb->csum); 730 desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
728 xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits); 731 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
732 return -1;
729 if (desc.offset != skb->len) { 733 if (desc.offset != skb->len) {
730 unsigned int csum2; 734 unsigned int csum2;
731 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0); 735 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
@@ -737,7 +741,8 @@ csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
737 return -1; 741 return -1;
738 return 0; 742 return 0;
739no_checksum: 743no_checksum:
740 xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits); 744 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
745 return -1;
741 if (desc.count) 746 if (desc.count)
742 return -1; 747 return -1;
743 return 0; 748 return 0;
@@ -821,10 +826,15 @@ tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
821{ 826{
822 if (len > desc->count) 827 if (len > desc->count)
823 len = desc->count; 828 len = desc->count;
824 if (skb_copy_bits(desc->skb, desc->offset, p, len)) 829 if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
830 dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
831 len, desc->count);
825 return 0; 832 return 0;
833 }
826 desc->offset += len; 834 desc->offset += len;
827 desc->count -= len; 835 desc->count -= len;
836 dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
837 len, desc->count);
828 return len; 838 return len;
829} 839}
830 840
@@ -863,6 +873,8 @@ tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
863static void 873static void
864tcp_check_recm(struct rpc_xprt *xprt) 874tcp_check_recm(struct rpc_xprt *xprt)
865{ 875{
876 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
877 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
866 if (xprt->tcp_offset == xprt->tcp_reclen) { 878 if (xprt->tcp_offset == xprt->tcp_reclen) {
867 xprt->tcp_flags |= XPRT_COPY_RECM; 879 xprt->tcp_flags |= XPRT_COPY_RECM;
868 xprt->tcp_offset = 0; 880 xprt->tcp_offset = 0;
@@ -907,6 +919,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
907 struct rpc_rqst *req; 919 struct rpc_rqst *req;
908 struct xdr_buf *rcvbuf; 920 struct xdr_buf *rcvbuf;
909 size_t len; 921 size_t len;
922 ssize_t r;
910 923
911 /* Find and lock the request corresponding to this xid */ 924 /* Find and lock the request corresponding to this xid */
912 spin_lock(&xprt->sock_lock); 925 spin_lock(&xprt->sock_lock);
@@ -927,15 +940,40 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
927 len = xprt->tcp_reclen - xprt->tcp_offset; 940 len = xprt->tcp_reclen - xprt->tcp_offset;
928 memcpy(&my_desc, desc, sizeof(my_desc)); 941 memcpy(&my_desc, desc, sizeof(my_desc));
929 my_desc.count = len; 942 my_desc.count = len;
930 xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 943 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
931 &my_desc, tcp_copy_data); 944 &my_desc, tcp_copy_data);
932 desc->count -= len; 945 desc->count -= r;
933 desc->offset += len; 946 desc->offset += r;
934 } else 947 } else
935 xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 948 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
936 desc, tcp_copy_data); 949 desc, tcp_copy_data);
937 xprt->tcp_copied += len; 950
938 xprt->tcp_offset += len; 951 if (r > 0) {
952 xprt->tcp_copied += r;
953 xprt->tcp_offset += r;
954 }
955 if (r != len) {
956 /* Error when copying to the receive buffer,
957 * usually because we weren't able to allocate
958 * additional buffer pages. All we can do now
959 * is turn off XPRT_COPY_DATA, so the request
960 * will not receive any additional updates,
961 * and time out.
962 * Any remaining data from this record will
963 * be discarded.
964 */
965 xprt->tcp_flags &= ~XPRT_COPY_DATA;
966 dprintk("RPC: XID %08x truncated request\n",
967 ntohl(xprt->tcp_xid));
968 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
969 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
970 goto out;
971 }
972
973 dprintk("RPC: XID %08x read %u bytes\n",
974 ntohl(xprt->tcp_xid), r);
975 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
976 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
939 977
940 if (xprt->tcp_copied == req->rq_private_buf.buflen) 978 if (xprt->tcp_copied == req->rq_private_buf.buflen)
941 xprt->tcp_flags &= ~XPRT_COPY_DATA; 979 xprt->tcp_flags &= ~XPRT_COPY_DATA;
@@ -944,6 +982,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
944 xprt->tcp_flags &= ~XPRT_COPY_DATA; 982 xprt->tcp_flags &= ~XPRT_COPY_DATA;
945 } 983 }
946 984
985out:
947 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) { 986 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
948 dprintk("RPC: %4d received reply complete\n", 987 dprintk("RPC: %4d received reply complete\n",
949 req->rq_task->tk_pid); 988 req->rq_task->tk_pid);
@@ -967,6 +1006,7 @@ tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
967 desc->count -= len; 1006 desc->count -= len;
968 desc->offset += len; 1007 desc->offset += len;
969 xprt->tcp_offset += len; 1008 xprt->tcp_offset += len;
1009 dprintk("RPC: discarded %u bytes\n", len);
970 tcp_check_recm(xprt); 1010 tcp_check_recm(xprt);
971} 1011}
972 1012
@@ -1064,8 +1104,7 @@ tcp_state_change(struct sock *sk)
1064 case TCP_SYN_RECV: 1104 case TCP_SYN_RECV:
1065 break; 1105 break;
1066 default: 1106 default:
1067 if (xprt_test_and_clear_connected(xprt)) 1107 xprt_disconnect(xprt);
1068 rpc_wake_up_status(&xprt->pending, -ENOTCONN);
1069 break; 1108 break;
1070 } 1109 }
1071 out: 1110 out:
@@ -1203,6 +1242,8 @@ xprt_transmit(struct rpc_task *task)
1203 list_add_tail(&req->rq_list, &xprt->recv); 1242 list_add_tail(&req->rq_list, &xprt->recv);
1204 spin_unlock_bh(&xprt->sock_lock); 1243 spin_unlock_bh(&xprt->sock_lock);
1205 xprt_reset_majortimeo(req); 1244 xprt_reset_majortimeo(req);
1245 /* Turn off autodisconnect */
1246 del_singleshot_timer_sync(&xprt->timer);
1206 } 1247 }
1207 } else if (!req->rq_bytes_sent) 1248 } else if (!req->rq_bytes_sent)
1208 return; 1249 return;
@@ -1333,8 +1374,6 @@ xprt_reserve(struct rpc_task *task)
1333 spin_lock(&xprt->xprt_lock); 1374 spin_lock(&xprt->xprt_lock);
1334 do_xprt_reserve(task); 1375 do_xprt_reserve(task);
1335 spin_unlock(&xprt->xprt_lock); 1376 spin_unlock(&xprt->xprt_lock);
1336 if (task->tk_rqstp)
1337 del_timer_sync(&xprt->timer);
1338 } 1377 }
1339} 1378}
1340 1379
@@ -1649,6 +1688,10 @@ xprt_shutdown(struct rpc_xprt *xprt)
1649 rpc_wake_up(&xprt->backlog); 1688 rpc_wake_up(&xprt->backlog);
1650 wake_up(&xprt->cong_wait); 1689 wake_up(&xprt->cong_wait);
1651 del_timer_sync(&xprt->timer); 1690 del_timer_sync(&xprt->timer);
1691
1692 /* synchronously wait for connect worker to finish */
1693 cancel_delayed_work(&xprt->sock_connect);
1694 flush_scheduled_work();
1652} 1695}
1653 1696
1654/* 1697/*