aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/acl.h10
-rw-r--r--fs/nfsd/nfs4acl.c13
-rw-r--r--fs/nfsd/nfs4callback.c19
-rw-r--r--fs/nfsd/nfs4proc.c39
-rw-r--r--fs/nfsd/nfs4state.c28
-rw-r--r--fs/nfsd/nfs4xdr.c30
-rw-r--r--fs/nfsd/nfsctl.c5
-rw-r--r--fs/nfsd/nfsd.h2
-rw-r--r--fs/nfsd/nfsfh.h14
-rw-r--r--fs/nfsd/nfsxdr.c2
-rw-r--r--fs/nfsd/vfs.c15
-rw-r--r--fs/nfsd/xdr4.h2
12 files changed, 129 insertions, 50 deletions
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index a812fd1b92a4..b481e1f5eecc 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -39,9 +39,13 @@ struct nfs4_acl;
39struct svc_fh; 39struct svc_fh;
40struct svc_rqst; 40struct svc_rqst;
41 41
42/* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to 42/*
43 * fit in a page: */ 43 * Maximum ACL we'll accept from a client; chosen (somewhat
44#define NFS4_ACL_MAX 170 44 * arbitrarily) so that kmalloc'ing the ACL shouldn't require a
45 * high-order allocation. This allows 204 ACEs on x86_64:
46 */
47#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \
48 / sizeof(struct nfs4_ace))
45 49
46struct nfs4_acl *nfs4_acl_new(int); 50struct nfs4_acl *nfs4_acl_new(int);
47int nfs4_acl_get_whotype(char *, u32); 51int nfs4_acl_get_whotype(char *, u32);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index d190e33d0ec2..6f3f392d48af 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -542,7 +542,10 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
542 * up setting a 3-element effective posix ACL with all 542 * up setting a 3-element effective posix ACL with all
543 * permissions zero. 543 * permissions zero.
544 */ 544 */
545 nace = 4 + state->users->n + state->groups->n; 545 if (!state->users->n && !state->groups->n)
546 nace = 3;
547 else /* Note we also include a MASK ACE in this case: */
548 nace = 4 + state->users->n + state->groups->n;
546 pacl = posix_acl_alloc(nace, GFP_KERNEL); 549 pacl = posix_acl_alloc(nace, GFP_KERNEL);
547 if (!pacl) 550 if (!pacl)
548 return ERR_PTR(-ENOMEM); 551 return ERR_PTR(-ENOMEM);
@@ -586,9 +589,11 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
586 add_to_mask(state, &state->groups->aces[i].perms); 589 add_to_mask(state, &state->groups->aces[i].perms);
587 } 590 }
588 591
589 pace++; 592 if (!state->users->n && !state->groups->n) {
590 pace->e_tag = ACL_MASK; 593 pace++;
591 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); 594 pace->e_tag = ACL_MASK;
595 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
596 }
592 597
593 pace++; 598 pace++;
594 pace->e_tag = ACL_OTHER; 599 pace->e_tag = ACL_OTHER;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 7f05cd140de3..39c8ef875f91 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include <linux/sunrpc/clnt.h> 34#include <linux/sunrpc/clnt.h>
35#include <linux/sunrpc/xprt.h>
35#include <linux/sunrpc/svc_xprt.h> 36#include <linux/sunrpc/svc_xprt.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include "nfsd.h" 38#include "nfsd.h"
@@ -635,6 +636,22 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
635 } 636 }
636} 637}
637 638
639static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
640{
641 struct rpc_xprt *xprt;
642
643 if (args->protocol != XPRT_TRANSPORT_BC_TCP)
644 return rpc_create(args);
645
646 xprt = args->bc_xprt->xpt_bc_xprt;
647 if (xprt) {
648 xprt_get(xprt);
649 return rpc_create_xprt(args, xprt);
650 }
651
652 return rpc_create(args);
653}
654
638static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) 655static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
639{ 656{
640 struct rpc_timeout timeparms = { 657 struct rpc_timeout timeparms = {
@@ -674,7 +691,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
674 args.authflavor = ses->se_cb_sec.flavor; 691 args.authflavor = ses->se_cb_sec.flavor;
675 } 692 }
676 /* Create RPC client */ 693 /* Create RPC client */
677 client = rpc_create(&args); 694 client = create_backchannel_client(&args);
678 if (IS_ERR(client)) { 695 if (IS_ERR(client)) {
679 dprintk("NFSD: couldn't create callback client: %ld\n", 696 dprintk("NFSD: couldn't create callback client: %ld\n",
680 PTR_ERR(client)); 697 PTR_ERR(client));
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 82189b208af3..d543222babf3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1273,6 +1273,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1273 struct nfsd4_op *op; 1273 struct nfsd4_op *op;
1274 struct nfsd4_operation *opdesc; 1274 struct nfsd4_operation *opdesc;
1275 struct nfsd4_compound_state *cstate = &resp->cstate; 1275 struct nfsd4_compound_state *cstate = &resp->cstate;
1276 struct svc_fh *current_fh = &cstate->current_fh;
1277 struct svc_fh *save_fh = &cstate->save_fh;
1276 int slack_bytes; 1278 int slack_bytes;
1277 u32 plen = 0; 1279 u32 plen = 0;
1278 __be32 status; 1280 __be32 status;
@@ -1288,11 +1290,11 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1288 resp->tag = args->tag; 1290 resp->tag = args->tag;
1289 resp->opcnt = 0; 1291 resp->opcnt = 0;
1290 resp->rqstp = rqstp; 1292 resp->rqstp = rqstp;
1291 resp->cstate.minorversion = args->minorversion; 1293 cstate->minorversion = args->minorversion;
1292 resp->cstate.replay_owner = NULL; 1294 cstate->replay_owner = NULL;
1293 resp->cstate.session = NULL; 1295 cstate->session = NULL;
1294 fh_init(&resp->cstate.current_fh, NFS4_FHSIZE); 1296 fh_init(current_fh, NFS4_FHSIZE);
1295 fh_init(&resp->cstate.save_fh, NFS4_FHSIZE); 1297 fh_init(save_fh, NFS4_FHSIZE);
1296 /* 1298 /*
1297 * Don't use the deferral mechanism for NFSv4; compounds make it 1299 * Don't use the deferral mechanism for NFSv4; compounds make it
1298 * too hard to avoid non-idempotency problems. 1300 * too hard to avoid non-idempotency problems.
@@ -1345,20 +1347,28 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1345 1347
1346 opdesc = OPDESC(op); 1348 opdesc = OPDESC(op);
1347 1349
1348 if (!cstate->current_fh.fh_dentry) { 1350 if (!current_fh->fh_dentry) {
1349 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { 1351 if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
1350 op->status = nfserr_nofilehandle; 1352 op->status = nfserr_nofilehandle;
1351 goto encode_op; 1353 goto encode_op;
1352 } 1354 }
1353 } else if (cstate->current_fh.fh_export->ex_fslocs.migrated && 1355 } else if (current_fh->fh_export->ex_fslocs.migrated &&
1354 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { 1356 !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
1355 op->status = nfserr_moved; 1357 op->status = nfserr_moved;
1356 goto encode_op; 1358 goto encode_op;
1357 } 1359 }
1358 1360
1361 fh_clear_wcc(current_fh);
1362
1359 /* If op is non-idempotent */ 1363 /* If op is non-idempotent */
1360 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { 1364 if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
1361 plen = opdesc->op_rsize_bop(rqstp, op); 1365 plen = opdesc->op_rsize_bop(rqstp, op);
1366 /*
1367 * If there's still another operation, make sure
1368 * we'll have space to at least encode an error:
1369 */
1370 if (resp->opcnt < args->opcnt)
1371 plen += COMPOUND_ERR_SLACK_SPACE;
1362 op->status = nfsd4_check_resp_size(resp, plen); 1372 op->status = nfsd4_check_resp_size(resp, plen);
1363 } 1373 }
1364 1374
@@ -1377,12 +1387,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1377 clear_current_stateid(cstate); 1387 clear_current_stateid(cstate);
1378 1388
1379 if (need_wrongsec_check(rqstp)) 1389 if (need_wrongsec_check(rqstp))
1380 op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); 1390 op->status = check_nfsd_access(current_fh->fh_export, rqstp);
1381 } 1391 }
1382 1392
1383encode_op: 1393encode_op:
1384 /* Only from SEQUENCE */ 1394 /* Only from SEQUENCE */
1385 if (resp->cstate.status == nfserr_replay_cache) { 1395 if (cstate->status == nfserr_replay_cache) {
1386 dprintk("%s NFS4.1 replay from cache\n", __func__); 1396 dprintk("%s NFS4.1 replay from cache\n", __func__);
1387 status = op->status; 1397 status = op->status;
1388 goto out; 1398 goto out;
@@ -1411,10 +1421,10 @@ encode_op:
1411 nfsd4_increment_op_stats(op->opnum); 1421 nfsd4_increment_op_stats(op->opnum);
1412 } 1422 }
1413 1423
1414 resp->cstate.status = status; 1424 cstate->status = status;
1415 fh_put(&resp->cstate.current_fh); 1425 fh_put(current_fh);
1416 fh_put(&resp->cstate.save_fh); 1426 fh_put(save_fh);
1417 BUG_ON(resp->cstate.replay_owner); 1427 BUG_ON(cstate->replay_owner);
1418out: 1428out:
1419 /* Reset deferral mechanism for RPC deferrals */ 1429 /* Reset deferral mechanism for RPC deferrals */
1420 rqstp->rq_usedeferral = 1; 1430 rqstp->rq_usedeferral = 1;
@@ -1523,7 +1533,8 @@ static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o
1523 1533
1524static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1534static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1525{ 1535{
1526 return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32); 1536 return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) *
1537 sizeof(__be32);
1527} 1538}
1528 1539
1529static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1540static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d5d070fbeb35..3ba65979a3cd 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1538,7 +1538,7 @@ out_err:
1538} 1538}
1539 1539
1540/* 1540/*
1541 * Cache a reply. nfsd4_check_drc_limit() has bounded the cache size. 1541 * Cache a reply. nfsd4_check_resp_size() has bounded the cache size.
1542 */ 1542 */
1543void 1543void
1544nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) 1544nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
@@ -1596,7 +1596,7 @@ nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
1596 * The sequence operation is not cached because we can use the slot and 1596 * The sequence operation is not cached because we can use the slot and
1597 * session values. 1597 * session values.
1598 */ 1598 */
1599__be32 1599static __be32
1600nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, 1600nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1601 struct nfsd4_sequence *seq) 1601 struct nfsd4_sequence *seq)
1602{ 1602{
@@ -1605,9 +1605,8 @@ nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
1605 1605
1606 dprintk("--> %s slot %p\n", __func__, slot); 1606 dprintk("--> %s slot %p\n", __func__, slot);
1607 1607
1608 /* Either returns 0 or nfserr_retry_uncached */
1609 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp); 1608 status = nfsd4_enc_sequence_replay(resp->rqstp->rq_argp, resp);
1610 if (status == nfserr_retry_uncached_rep) 1609 if (status)
1611 return status; 1610 return status;
1612 1611
1613 /* The sequence operation has been encoded, cstate->datap set. */ 1612 /* The sequence operation has been encoded, cstate->datap set. */
@@ -2287,7 +2286,8 @@ out:
2287 if (!list_empty(&clp->cl_revoked)) 2286 if (!list_empty(&clp->cl_revoked))
2288 seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED; 2287 seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
2289out_no_session: 2288out_no_session:
2290 kfree(conn); 2289 if (conn)
2290 free_conn(conn);
2291 spin_unlock(&nn->client_lock); 2291 spin_unlock(&nn->client_lock);
2292 return status; 2292 return status;
2293out_put_session: 2293out_put_session:
@@ -3627,8 +3627,11 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
3627 return nfserr_bad_stateid; 3627 return nfserr_bad_stateid;
3628 status = lookup_clientid(&stateid->si_opaque.so_clid, sessions, 3628 status = lookup_clientid(&stateid->si_opaque.so_clid, sessions,
3629 nn, &cl); 3629 nn, &cl);
3630 if (status == nfserr_stale_clientid) 3630 if (status == nfserr_stale_clientid) {
3631 if (sessions)
3632 return nfserr_bad_stateid;
3631 return nfserr_stale_stateid; 3633 return nfserr_stale_stateid;
3634 }
3632 if (status) 3635 if (status)
3633 return status; 3636 return status;
3634 *s = find_stateid_by_type(cl, stateid, typemask); 3637 *s = find_stateid_by_type(cl, stateid, typemask);
@@ -5062,7 +5065,6 @@ nfs4_state_destroy_net(struct net *net)
5062 int i; 5065 int i;
5063 struct nfs4_client *clp = NULL; 5066 struct nfs4_client *clp = NULL;
5064 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 5067 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
5065 struct rb_node *node, *tmp;
5066 5068
5067 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 5069 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5068 while (!list_empty(&nn->conf_id_hashtbl[i])) { 5070 while (!list_empty(&nn->conf_id_hashtbl[i])) {
@@ -5071,13 +5073,11 @@ nfs4_state_destroy_net(struct net *net)
5071 } 5073 }
5072 } 5074 }
5073 5075
5074 node = rb_first(&nn->unconf_name_tree); 5076 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
5075 while (node != NULL) { 5077 while (!list_empty(&nn->unconf_id_hashtbl[i])) {
5076 tmp = node; 5078 clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
5077 node = rb_next(tmp); 5079 destroy_client(clp);
5078 clp = rb_entry(tmp, struct nfs4_client, cl_namenode); 5080 }
5079 rb_erase(tmp, &nn->unconf_name_tree);
5080 destroy_client(clp);
5081 } 5081 }
5082 5082
5083 kfree(nn->sessionid_hashtbl); 5083 kfree(nn->sessionid_hashtbl);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 63f2395c57ed..2723c1badd01 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -294,7 +294,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
294 READ32(nace); 294 READ32(nace);
295 295
296 if (nace > NFS4_ACL_MAX) 296 if (nace > NFS4_ACL_MAX)
297 return nfserr_resource; 297 return nfserr_fbig;
298 298
299 *acl = nfs4_acl_new(nace); 299 *acl = nfs4_acl_new(nace);
300 if (*acl == NULL) 300 if (*acl == NULL)
@@ -1222,7 +1222,6 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1222 } 1222 }
1223 write->wr_head.iov_base = p; 1223 write->wr_head.iov_base = p;
1224 write->wr_head.iov_len = avail; 1224 write->wr_head.iov_len = avail;
1225 WARN_ON(avail != (XDR_QUADLEN(avail) << 2));
1226 write->wr_pagelist = argp->pagelist; 1225 write->wr_pagelist = argp->pagelist;
1227 1226
1228 len = XDR_QUADLEN(write->wr_buflen) << 2; 1227 len = XDR_QUADLEN(write->wr_buflen) << 2;
@@ -2483,6 +2482,8 @@ out_acl:
2483 goto out; 2482 goto out;
2484 } 2483 }
2485 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2484 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2485 if ((buflen -= 16) < 0)
2486 goto out_resource;
2486 WRITE32(3); 2487 WRITE32(3);
2487 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); 2488 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2488 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1); 2489 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
@@ -2499,8 +2500,10 @@ out:
2499 security_release_secctx(context, contextlen); 2500 security_release_secctx(context, contextlen);
2500#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ 2501#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2501 kfree(acl); 2502 kfree(acl);
2502 if (tempfh) 2503 if (tempfh) {
2503 fh_put(tempfh); 2504 fh_put(tempfh);
2505 kfree(tempfh);
2506 }
2504 return status; 2507 return status;
2505out_nfserr: 2508out_nfserr:
2506 status = nfserrno(err); 2509 status = nfserrno(err);
@@ -3471,6 +3474,9 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3471 struct nfsd4_test_stateid_id *stateid, *next; 3474 struct nfsd4_test_stateid_id *stateid, *next;
3472 __be32 *p; 3475 __be32 *p;
3473 3476
3477 if (nfserr)
3478 return nfserr;
3479
3474 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids)); 3480 RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
3475 *p++ = htonl(test_stateid->ts_num_ids); 3481 *p++ = htonl(test_stateid->ts_num_ids);
3476 3482
@@ -3579,8 +3585,6 @@ __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3579 return 0; 3585 return 0;
3580 3586
3581 session = resp->cstate.session; 3587 session = resp->cstate.session;
3582 if (session == NULL)
3583 return 0;
3584 3588
3585 if (xb->page_len == 0) { 3589 if (xb->page_len == 0) {
3586 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad; 3590 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
@@ -3620,9 +3624,17 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3620 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) || 3624 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3621 !nfsd4_enc_ops[op->opnum]); 3625 !nfsd4_enc_ops[op->opnum]);
3622 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); 3626 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3623 /* nfsd4_check_drc_limit guarantees enough room for error status */ 3627 /* nfsd4_check_resp_size guarantees enough room for error status */
3624 if (!op->status) 3628 if (!op->status)
3625 op->status = nfsd4_check_resp_size(resp, 0); 3629 op->status = nfsd4_check_resp_size(resp, 0);
3630 if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
3631 struct nfsd4_slot *slot = resp->cstate.slot;
3632
3633 if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
3634 op->status = nfserr_rep_too_big_to_cache;
3635 else
3636 op->status = nfserr_rep_too_big;
3637 }
3626 if (so) { 3638 if (so) {
3627 so->so_replay.rp_status = op->status; 3639 so->so_replay.rp_status = op->status;
3628 so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1); 3640 so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1);
@@ -3691,6 +3703,12 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
3691int 3703int
3692nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) 3704nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3693{ 3705{
3706 if (rqstp->rq_arg.head[0].iov_len % 4) {
3707 /* client is nuts */
3708 dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
3709 __func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
3710 return 0;
3711 }
3694 args->p = p; 3712 args->p = p;
3695 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; 3713 args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3696 args->pagelist = rqstp->rq_arg.pages; 3714 args->pagelist = rqstp->rq_arg.pages;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 7f555179bf81..f34d9de802ab 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -699,6 +699,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net)
699 if (err != 0 || fd < 0) 699 if (err != 0 || fd < 0)
700 return -EINVAL; 700 return -EINVAL;
701 701
702 if (svc_alien_sock(net, fd)) {
703 printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
704 return -EINVAL;
705 }
706
702 err = nfsd_create_serv(net); 707 err = nfsd_create_serv(net);
703 if (err != 0) 708 if (err != 0)
704 return err; 709 return err;
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 30f34ab02137..479eb681c27c 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -282,7 +282,7 @@ void nfsd_lockd_shutdown(void);
282 * reason. 282 * reason.
283 */ 283 */
284#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ 284#define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */
285#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ 285#define COMPOUND_ERR_SLACK_SPACE 16 /* OP_SETATTR */
286 286
287#define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */ 287#define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */
288 288
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
index 4775bc4896c8..ad67964d0bb1 100644
--- a/fs/nfsd/nfsfh.h
+++ b/fs/nfsd/nfsfh.h
@@ -133,6 +133,17 @@ fh_init(struct svc_fh *fhp, int maxsize)
133 133
134#ifdef CONFIG_NFSD_V3 134#ifdef CONFIG_NFSD_V3
135/* 135/*
136 * The wcc data stored in current_fh should be cleared
137 * between compound ops.
138 */
139static inline void
140fh_clear_wcc(struct svc_fh *fhp)
141{
142 fhp->fh_post_saved = 0;
143 fhp->fh_pre_saved = 0;
144}
145
146/*
136 * Fill in the pre_op attr for the wcc data 147 * Fill in the pre_op attr for the wcc data
137 */ 148 */
138static inline void 149static inline void
@@ -152,7 +163,8 @@ fill_pre_wcc(struct svc_fh *fhp)
152 163
153extern void fill_post_wcc(struct svc_fh *); 164extern void fill_post_wcc(struct svc_fh *);
154#else 165#else
155#define fill_pre_wcc(ignored) 166#define fh_clear_wcc(ignored)
167#define fill_pre_wcc(ignored)
156#define fill_post_wcc(notused) 168#define fill_post_wcc(notused)
157#endif /* CONFIG_NFSD_V3 */ 169#endif /* CONFIG_NFSD_V3 */
158 170
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index b17d93214d01..9c769a47ac5a 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -152,7 +152,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
152 type = (stat->mode & S_IFMT); 152 type = (stat->mode & S_IFMT);
153 153
154 *p++ = htonl(nfs_ftypes[type >> 12]); 154 *p++ = htonl(nfs_ftypes[type >> 12]);
155 *p++ = htonl((u32) (stat->mode & S_IALLUGO)); 155 *p++ = htonl((u32) stat->mode);
156 *p++ = htonl((u32) stat->nlink); 156 *p++ = htonl((u32) stat->nlink);
157 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); 157 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
158 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); 158 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 915808b36df7..16f0673a423c 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -404,6 +404,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
404 umode_t ftype = 0; 404 umode_t ftype = 0;
405 __be32 err; 405 __be32 err;
406 int host_err; 406 int host_err;
407 bool get_write_count;
407 int size_change = 0; 408 int size_change = 0;
408 409
409 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) 410 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
@@ -411,10 +412,18 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
411 if (iap->ia_valid & ATTR_SIZE) 412 if (iap->ia_valid & ATTR_SIZE)
412 ftype = S_IFREG; 413 ftype = S_IFREG;
413 414
415 /* Callers that do fh_verify should do the fh_want_write: */
416 get_write_count = !fhp->fh_dentry;
417
414 /* Get inode */ 418 /* Get inode */
415 err = fh_verify(rqstp, fhp, ftype, accmode); 419 err = fh_verify(rqstp, fhp, ftype, accmode);
416 if (err) 420 if (err)
417 goto out; 421 goto out;
422 if (get_write_count) {
423 host_err = fh_want_write(fhp);
424 if (host_err)
425 return nfserrno(host_err);
426 }
418 427
419 dentry = fhp->fh_dentry; 428 dentry = fhp->fh_dentry;
420 inode = dentry->d_inode; 429 inode = dentry->d_inode;
@@ -1706,10 +1715,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1706 dput(odentry); 1715 dput(odentry);
1707 out_nfserr: 1716 out_nfserr:
1708 err = nfserrno(host_err); 1717 err = nfserrno(host_err);
1709 1718 /*
1710 /* we cannot reply on fh_unlock on the two filehandles, 1719 * We cannot rely on fh_unlock on the two filehandles,
1711 * as that would do the wrong thing if the two directories 1720 * as that would do the wrong thing if the two directories
1712 * were the same, so again we do it by hand 1721 * were the same, so again we do it by hand.
1713 */ 1722 */
1714 fill_post_wcc(ffhp); 1723 fill_post_wcc(ffhp);
1715 fill_post_wcc(tfhp); 1724 fill_post_wcc(tfhp);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index d278a0d03496..5ea7df305083 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -574,8 +574,6 @@ extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
574 struct nfsd4_compound_state *, 574 struct nfsd4_compound_state *,
575 struct nfsd4_setclientid_confirm *setclientid_confirm); 575 struct nfsd4_setclientid_confirm *setclientid_confirm);
576extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp); 576extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
577extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
578 struct nfsd4_sequence *seq);
579extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, 577extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
580 struct nfsd4_compound_state *, struct nfsd4_exchange_id *); 578 struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
581extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *); 579extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *);