aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 13:17:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 13:17:13 -0400
commit0ff08ba5d066619f9973bfcdb5a21320d54219d0 (patch)
tree526e4a5799eb3023e9d5d81e81c0964b1d928a3e
parentc72bb316916b1a6cf35e1d5238566ef27b0b7f80 (diff)
parentd109148111cdfcdae94f797dc142468bd0ff7557 (diff)
Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from Bruce Fields: "Changes this time include: - 4.1 enabled on the server by default: the last 4.1-specific issues I know of are fixed, so we're not going to find the rest of the bugs without more exposure. - Experimental support for NFSv4.2 MAC Labeling (to allow running selinux over NFS), from Dave Quigley. - Fixes for some delicate cache/upcall races that could cause rare server hangs; thanks to Neil Brown and Bodo Stroesser for extreme debugging persistence. - Fixes for some bugs found at the recent NFS bakeathon, mostly v4 and v4.1-specific, but also a generic bug handling fragmented rpc calls" * 'for-3.11' of git://linux-nfs.org/~bfields/linux: (31 commits) nfsd4: support minorversion 1 by default nfsd4: allow destroy_session over destroyed session svcrpc: fix failures to handle -1 uid's sunrpc: Don't schedule an upcall on a replaced cache entry. net/sunrpc: xpt_auth_cache should be ignored when expired. sunrpc/cache: ensure items removed from cache do not have pending upcalls. sunrpc/cache: use cache_fresh_unlocked consistently and correctly. sunrpc/cache: remove races with queuing an upcall. nfsd4: return delegation immediately if lease fails nfsd4: do not throw away 4.1 lock state on last unlock nfsd4: delegation-based open reclaims should bypass permissions svcrpc: don't error out on small tcp fragment svcrpc: fix handling of too-short rpc's nfsd4: minor read_buf cleanup nfsd4: fix decoding of compounds across page boundaries nfsd4: clean up nfs4_open_delegation NFSD: Don't give out read delegations on creates nfsd4: allow client to send no cb_sec flavors nfsd4: fail attempts to request gss on the backchannel nfsd4: implement minimal SP4_MACH_CRED ...
-rw-r--r--fs/nfsd/Kconfig16
-rw-r--r--fs/nfsd/nfs4proc.c44
-rw-r--r--fs/nfsd/nfs4state.c225
-rw-r--r--fs/nfsd/nfs4xdr.c169
-rw-r--r--fs/nfsd/nfsd.h20
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/state.h1
-rw-r--r--fs/nfsd/vfs.c28
-rw-r--r--fs/nfsd/vfs.h7
-rw-r--r--fs/nfsd/xdr4.h4
-rw-r--r--include/linux/sunrpc/cache.h49
-rw-r--r--include/linux/sunrpc/gss_api.h2
-rw-r--r--include/linux/sunrpc/svcauth.h11
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c5
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c10
-rw-r--r--net/sunrpc/cache.c83
-rw-r--r--net/sunrpc/svcauth_unix.c6
-rw-r--r--net/sunrpc/svcsock.c9
-rw-r--r--net/sunrpc/xprtsock.c1
-rw-r--r--security/capability.c2
20 files changed, 512 insertions, 182 deletions
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index 430b6872806f..dc8f1ef665ce 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -81,6 +81,22 @@ config NFSD_V4
81 81
82 If unsure, say N. 82 If unsure, say N.
83 83
84config NFSD_V4_SECURITY_LABEL
85 bool "Provide Security Label support for NFSv4 server"
86 depends on NFSD_V4 && SECURITY
87 help
88
89 Say Y here if you want enable fine-grained security label attribute
90 support for NFS version 4. Security labels allow security modules like
91 SELinux and Smack to label files to facilitate enforcement of their policies.
92 Without this an NFSv4 mount will have the same label on each file.
93
94 If you do not wish to enable fine-grained security labels SELinux or
95 Smack policies on NFSv4 files, say N.
96
97 WARNING: there is still a chance of backwards-incompatible protocol changes.
98 For now we recommend "Y" only for developers and testers."
99
84config NFSD_FAULT_INJECTION 100config NFSD_FAULT_INJECTION
85 bool "NFS server manual fault injection" 101 bool "NFS server manual fault injection"
86 depends on NFSD_V4 && DEBUG_KERNEL 102 depends on NFSD_V4 && DEBUG_KERNEL
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 27d74a294515..a7cee864e7b2 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -42,6 +42,36 @@
42#include "current_stateid.h" 42#include "current_stateid.h"
43#include "netns.h" 43#include "netns.h"
44 44
45#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
46#include <linux/security.h>
47
48static inline void
49nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
50{
51 struct inode *inode = resfh->fh_dentry->d_inode;
52 int status;
53
54 mutex_lock(&inode->i_mutex);
55 status = security_inode_setsecctx(resfh->fh_dentry,
56 label->data, label->len);
57 mutex_unlock(&inode->i_mutex);
58
59 if (status)
60 /*
61 * XXX: We should really fail the whole open, but we may
62 * already have created a new file, so it may be too
63 * late. For now this seems the least of evils:
64 */
65 bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
66
67 return;
68}
69#else
70static inline void
71nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
72{ }
73#endif
74
45#define NFSDDBG_FACILITY NFSDDBG_PROC 75#define NFSDDBG_FACILITY NFSDDBG_PROC
46 76
47static u32 nfsd_attrmask[] = { 77static u32 nfsd_attrmask[] = {
@@ -239,6 +269,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
239 (u32 *)open->op_verf.data, 269 (u32 *)open->op_verf.data,
240 &open->op_truncate, &open->op_created); 270 &open->op_truncate, &open->op_created);
241 271
272 if (!status && open->op_label.len)
273 nfsd4_security_inode_setsecctx(resfh, &open->op_label, open->op_bmval);
274
242 /* 275 /*
243 * Following rfc 3530 14.2.16, use the returned bitmask 276 * Following rfc 3530 14.2.16, use the returned bitmask
244 * to indicate which attributes we used to store the 277 * to indicate which attributes we used to store the
@@ -263,7 +296,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
263 296
264 nfsd4_set_open_owner_reply_cache(cstate, open, resfh); 297 nfsd4_set_open_owner_reply_cache(cstate, open, resfh);
265 accmode = NFSD_MAY_NOP; 298 accmode = NFSD_MAY_NOP;
266 if (open->op_created) 299 if (open->op_created ||
300 open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
267 accmode |= NFSD_MAY_OWNER_OVERRIDE; 301 accmode |= NFSD_MAY_OWNER_OVERRIDE;
268 status = do_open_permission(rqstp, resfh, open, accmode); 302 status = do_open_permission(rqstp, resfh, open, accmode);
269 set_change_info(&open->op_cinfo, current_fh); 303 set_change_info(&open->op_cinfo, current_fh);
@@ -637,6 +671,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
637 if (status) 671 if (status)
638 goto out; 672 goto out;
639 673
674 if (create->cr_label.len)
675 nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval);
676
640 if (create->cr_acl != NULL) 677 if (create->cr_acl != NULL)
641 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, 678 do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
642 create->cr_bmval); 679 create->cr_bmval);
@@ -916,6 +953,11 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
916 setattr->sa_acl); 953 setattr->sa_acl);
917 if (status) 954 if (status)
918 goto out; 955 goto out;
956 if (setattr->sa_label.len)
957 status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh,
958 &setattr->sa_label);
959 if (status)
960 goto out;
919 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 961 status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
920 0, (time_t)0); 962 0, (time_t)0);
921out: 963out:
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f17051838b41..280acef6f0dc 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -97,19 +97,20 @@ nfs4_lock_state(void)
97 97
98static void free_session(struct nfsd4_session *); 98static void free_session(struct nfsd4_session *);
99 99
100void nfsd4_put_session(struct nfsd4_session *ses) 100static bool is_session_dead(struct nfsd4_session *ses)
101{ 101{
102 atomic_dec(&ses->se_ref); 102 return ses->se_flags & NFS4_SESSION_DEAD;
103} 103}
104 104
105static bool is_session_dead(struct nfsd4_session *ses) 105void nfsd4_put_session(struct nfsd4_session *ses)
106{ 106{
107 return ses->se_flags & NFS4_SESSION_DEAD; 107 if (atomic_dec_and_test(&ses->se_ref) && is_session_dead(ses))
108 free_session(ses);
108} 109}
109 110
110static __be32 mark_session_dead_locked(struct nfsd4_session *ses) 111static __be32 mark_session_dead_locked(struct nfsd4_session *ses, int ref_held_by_me)
111{ 112{
112 if (atomic_read(&ses->se_ref)) 113 if (atomic_read(&ses->se_ref) > ref_held_by_me)
113 return nfserr_jukebox; 114 return nfserr_jukebox;
114 ses->se_flags |= NFS4_SESSION_DEAD; 115 ses->se_flags |= NFS4_SESSION_DEAD;
115 return nfs_ok; 116 return nfs_ok;
@@ -364,19 +365,12 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp)
364} 365}
365 366
366static struct nfs4_delegation * 367static struct nfs4_delegation *
367alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh, u32 type) 368alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh)
368{ 369{
369 struct nfs4_delegation *dp; 370 struct nfs4_delegation *dp;
370 struct nfs4_file *fp = stp->st_file; 371 struct nfs4_file *fp = stp->st_file;
371 372
372 dprintk("NFSD alloc_init_deleg\n"); 373 dprintk("NFSD alloc_init_deleg\n");
373 /*
374 * Major work on the lease subsystem (for example, to support
375 * calbacks on stat) will be required before we can support
376 * write delegations properly.
377 */
378 if (type != NFS4_OPEN_DELEGATE_READ)
379 return NULL;
380 if (fp->fi_had_conflict) 374 if (fp->fi_had_conflict)
381 return NULL; 375 return NULL;
382 if (num_delegations > max_delegations) 376 if (num_delegations > max_delegations)
@@ -397,7 +391,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
397 INIT_LIST_HEAD(&dp->dl_recall_lru); 391 INIT_LIST_HEAD(&dp->dl_recall_lru);
398 get_nfs4_file(fp); 392 get_nfs4_file(fp);
399 dp->dl_file = fp; 393 dp->dl_file = fp;
400 dp->dl_type = type; 394 dp->dl_type = NFS4_OPEN_DELEGATE_READ;
401 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle); 395 fh_copy_shallow(&dp->dl_fh, &current_fh->fh_handle);
402 dp->dl_time = 0; 396 dp->dl_time = 0;
403 atomic_set(&dp->dl_count, 1); 397 atomic_set(&dp->dl_count, 1);
@@ -1188,6 +1182,9 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1188 target->cr_gid = source->cr_gid; 1182 target->cr_gid = source->cr_gid;
1189 target->cr_group_info = source->cr_group_info; 1183 target->cr_group_info = source->cr_group_info;
1190 get_group_info(target->cr_group_info); 1184 get_group_info(target->cr_group_info);
1185 target->cr_gss_mech = source->cr_gss_mech;
1186 if (source->cr_gss_mech)
1187 gss_mech_get(source->cr_gss_mech);
1191 return 0; 1188 return 0;
1192} 1189}
1193 1190
@@ -1262,6 +1259,31 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1262 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal); 1259 return 0 == strcmp(cr1->cr_principal, cr2->cr_principal);
1263} 1260}
1264 1261
1262static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp)
1263{
1264 struct svc_cred *cr = &rqstp->rq_cred;
1265 u32 service;
1266
1267 service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor);
1268 return service == RPC_GSS_SVC_INTEGRITY ||
1269 service == RPC_GSS_SVC_PRIVACY;
1270}
1271
1272static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp)
1273{
1274 struct svc_cred *cr = &rqstp->rq_cred;
1275
1276 if (!cl->cl_mach_cred)
1277 return true;
1278 if (cl->cl_cred.cr_gss_mech != cr->cr_gss_mech)
1279 return false;
1280 if (!svc_rqst_integrity_protected(rqstp))
1281 return false;
1282 if (!cr->cr_principal)
1283 return false;
1284 return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal);
1285}
1286
1265static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn) 1287static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1266{ 1288{
1267 static u32 current_clientid = 1; 1289 static u32 current_clientid = 1;
@@ -1639,16 +1661,16 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1639 if (exid->flags & ~EXCHGID4_FLAG_MASK_A) 1661 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1640 return nfserr_inval; 1662 return nfserr_inval;
1641 1663
1642 /* Currently only support SP4_NONE */
1643 switch (exid->spa_how) { 1664 switch (exid->spa_how) {
1665 case SP4_MACH_CRED:
1666 if (!svc_rqst_integrity_protected(rqstp))
1667 return nfserr_inval;
1644 case SP4_NONE: 1668 case SP4_NONE:
1645 break; 1669 break;
1646 default: /* checked by xdr code */ 1670 default: /* checked by xdr code */
1647 WARN_ON_ONCE(1); 1671 WARN_ON_ONCE(1);
1648 case SP4_SSV: 1672 case SP4_SSV:
1649 return nfserr_encr_alg_unsupp; 1673 return nfserr_encr_alg_unsupp;
1650 case SP4_MACH_CRED:
1651 return nfserr_serverfault; /* no excuse :-/ */
1652 } 1674 }
1653 1675
1654 /* Cases below refer to rfc 5661 section 18.35.4: */ 1676 /* Cases below refer to rfc 5661 section 18.35.4: */
@@ -1663,6 +1685,10 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1663 status = nfserr_inval; 1685 status = nfserr_inval;
1664 goto out; 1686 goto out;
1665 } 1687 }
1688 if (!mach_creds_match(conf, rqstp)) {
1689 status = nfserr_wrong_cred;
1690 goto out;
1691 }
1666 if (!creds_match) { /* case 9 */ 1692 if (!creds_match) { /* case 9 */
1667 status = nfserr_perm; 1693 status = nfserr_perm;
1668 goto out; 1694 goto out;
@@ -1709,7 +1735,8 @@ out_new:
1709 status = nfserr_jukebox; 1735 status = nfserr_jukebox;
1710 goto out; 1736 goto out;
1711 } 1737 }
1712 new->cl_minorversion = 1; 1738 new->cl_minorversion = cstate->minorversion;
1739 new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
1713 1740
1714 gen_clid(new, nn); 1741 gen_clid(new, nn);
1715 add_to_unconfirmed(new); 1742 add_to_unconfirmed(new);
@@ -1839,6 +1866,24 @@ static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
1839 return nfs_ok; 1866 return nfs_ok;
1840} 1867}
1841 1868
1869static __be32 nfsd4_check_cb_sec(struct nfsd4_cb_sec *cbs)
1870{
1871 switch (cbs->flavor) {
1872 case RPC_AUTH_NULL:
1873 case RPC_AUTH_UNIX:
1874 return nfs_ok;
1875 default:
1876 /*
1877 * GSS case: the spec doesn't allow us to return this
1878 * error. But it also doesn't allow us not to support
1879 * GSS.
1880 * I'd rather this fail hard than return some error the
1881 * client might think it can already handle:
1882 */
1883 return nfserr_encr_alg_unsupp;
1884 }
1885}
1886
1842__be32 1887__be32
1843nfsd4_create_session(struct svc_rqst *rqstp, 1888nfsd4_create_session(struct svc_rqst *rqstp,
1844 struct nfsd4_compound_state *cstate, 1889 struct nfsd4_compound_state *cstate,
@@ -1854,6 +1899,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1854 1899
1855 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1900 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1856 return nfserr_inval; 1901 return nfserr_inval;
1902 status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
1903 if (status)
1904 return status;
1857 status = check_forechannel_attrs(&cr_ses->fore_channel, nn); 1905 status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
1858 if (status) 1906 if (status)
1859 return status; 1907 return status;
@@ -1874,6 +1922,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1874 WARN_ON_ONCE(conf && unconf); 1922 WARN_ON_ONCE(conf && unconf);
1875 1923
1876 if (conf) { 1924 if (conf) {
1925 status = nfserr_wrong_cred;
1926 if (!mach_creds_match(conf, rqstp))
1927 goto out_free_conn;
1877 cs_slot = &conf->cl_cs_slot; 1928 cs_slot = &conf->cl_cs_slot;
1878 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1929 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1879 if (status == nfserr_replay_cache) { 1930 if (status == nfserr_replay_cache) {
@@ -1890,6 +1941,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1890 status = nfserr_clid_inuse; 1941 status = nfserr_clid_inuse;
1891 goto out_free_conn; 1942 goto out_free_conn;
1892 } 1943 }
1944 status = nfserr_wrong_cred;
1945 if (!mach_creds_match(unconf, rqstp))
1946 goto out_free_conn;
1893 cs_slot = &unconf->cl_cs_slot; 1947 cs_slot = &unconf->cl_cs_slot;
1894 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1948 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1895 if (status) { 1949 if (status) {
@@ -1957,7 +2011,11 @@ __be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state
1957{ 2011{
1958 struct nfsd4_session *session = cstate->session; 2012 struct nfsd4_session *session = cstate->session;
1959 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 2013 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2014 __be32 status;
1960 2015
2016 status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
2017 if (status)
2018 return status;
1961 spin_lock(&nn->client_lock); 2019 spin_lock(&nn->client_lock);
1962 session->se_cb_prog = bc->bc_cb_program; 2020 session->se_cb_prog = bc->bc_cb_program;
1963 session->se_cb_sec = bc->bc_cb_sec; 2021 session->se_cb_sec = bc->bc_cb_sec;
@@ -1986,6 +2044,9 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1986 status = nfserr_badsession; 2044 status = nfserr_badsession;
1987 if (!session) 2045 if (!session)
1988 goto out; 2046 goto out;
2047 status = nfserr_wrong_cred;
2048 if (!mach_creds_match(session->se_client, rqstp))
2049 goto out;
1989 status = nfsd4_map_bcts_dir(&bcts->dir); 2050 status = nfsd4_map_bcts_dir(&bcts->dir);
1990 if (status) 2051 if (status)
1991 goto out; 2052 goto out;
@@ -2014,6 +2075,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2014{ 2075{
2015 struct nfsd4_session *ses; 2076 struct nfsd4_session *ses;
2016 __be32 status; 2077 __be32 status;
2078 int ref_held_by_me = 0;
2017 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id); 2079 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id);
2018 2080
2019 nfs4_lock_state(); 2081 nfs4_lock_state();
@@ -2021,6 +2083,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2021 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) { 2083 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2022 if (!nfsd4_last_compound_op(r)) 2084 if (!nfsd4_last_compound_op(r))
2023 goto out; 2085 goto out;
2086 ref_held_by_me++;
2024 } 2087 }
2025 dump_sessionid(__func__, &sessionid->sessionid); 2088 dump_sessionid(__func__, &sessionid->sessionid);
2026 spin_lock(&nn->client_lock); 2089 spin_lock(&nn->client_lock);
@@ -2028,17 +2091,22 @@ nfsd4_destroy_session(struct svc_rqst *r,
2028 status = nfserr_badsession; 2091 status = nfserr_badsession;
2029 if (!ses) 2092 if (!ses)
2030 goto out_client_lock; 2093 goto out_client_lock;
2031 status = mark_session_dead_locked(ses); 2094 status = nfserr_wrong_cred;
2032 if (status) 2095 if (!mach_creds_match(ses->se_client, r))
2033 goto out_client_lock; 2096 goto out_client_lock;
2097 nfsd4_get_session_locked(ses);
2098 status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2099 if (status)
2100 goto out_put_session;
2034 unhash_session(ses); 2101 unhash_session(ses);
2035 spin_unlock(&nn->client_lock); 2102 spin_unlock(&nn->client_lock);
2036 2103
2037 nfsd4_probe_callback_sync(ses->se_client); 2104 nfsd4_probe_callback_sync(ses->se_client);
2038 2105
2039 spin_lock(&nn->client_lock); 2106 spin_lock(&nn->client_lock);
2040 free_session(ses);
2041 status = nfs_ok; 2107 status = nfs_ok;
2108out_put_session:
2109 nfsd4_put_session(ses);
2042out_client_lock: 2110out_client_lock:
2043 spin_unlock(&nn->client_lock); 2111 spin_unlock(&nn->client_lock);
2044out: 2112out:
@@ -2058,26 +2126,31 @@ static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_s
2058 return NULL; 2126 return NULL;
2059} 2127}
2060 2128
2061static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses) 2129static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2062{ 2130{
2063 struct nfs4_client *clp = ses->se_client; 2131 struct nfs4_client *clp = ses->se_client;
2064 struct nfsd4_conn *c; 2132 struct nfsd4_conn *c;
2133 __be32 status = nfs_ok;
2065 int ret; 2134 int ret;
2066 2135
2067 spin_lock(&clp->cl_lock); 2136 spin_lock(&clp->cl_lock);
2068 c = __nfsd4_find_conn(new->cn_xprt, ses); 2137 c = __nfsd4_find_conn(new->cn_xprt, ses);
2069 if (c) { 2138 if (c)
2070 spin_unlock(&clp->cl_lock); 2139 goto out_free;
2071 free_conn(new); 2140 status = nfserr_conn_not_bound_to_session;
2072 return; 2141 if (clp->cl_mach_cred)
2073 } 2142 goto out_free;
2074 __nfsd4_hash_conn(new, ses); 2143 __nfsd4_hash_conn(new, ses);
2075 spin_unlock(&clp->cl_lock); 2144 spin_unlock(&clp->cl_lock);
2076 ret = nfsd4_register_conn(new); 2145 ret = nfsd4_register_conn(new);
2077 if (ret) 2146 if (ret)
2078 /* oops; xprt is already down: */ 2147 /* oops; xprt is already down: */
2079 nfsd4_conn_lost(&new->cn_xpt_user); 2148 nfsd4_conn_lost(&new->cn_xpt_user);
2080 return; 2149 return nfs_ok;
2150out_free:
2151 spin_unlock(&clp->cl_lock);
2152 free_conn(new);
2153 return status;
2081} 2154}
2082 2155
2083static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) 2156static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session)
@@ -2169,8 +2242,10 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2169 if (status) 2242 if (status)
2170 goto out_put_session; 2243 goto out_put_session;
2171 2244
2172 nfsd4_sequence_check_conn(conn, session); 2245 status = nfsd4_sequence_check_conn(conn, session);
2173 conn = NULL; 2246 conn = NULL;
2247 if (status)
2248 goto out_put_session;
2174 2249
2175 /* Success! bump slot seqid */ 2250 /* Success! bump slot seqid */
2176 slot->sl_seqid = seq->seqid; 2251 slot->sl_seqid = seq->seqid;
@@ -2232,7 +2307,10 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2232 status = nfserr_stale_clientid; 2307 status = nfserr_stale_clientid;
2233 goto out; 2308 goto out;
2234 } 2309 }
2235 2310 if (!mach_creds_match(clp, rqstp)) {
2311 status = nfserr_wrong_cred;
2312 goto out;
2313 }
2236 expire_client(clp); 2314 expire_client(clp);
2237out: 2315out:
2238 nfs4_unlock_state(); 2316 nfs4_unlock_state();
@@ -2940,13 +3018,13 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f
2940 return fl; 3018 return fl;
2941} 3019}
2942 3020
2943static int nfs4_setlease(struct nfs4_delegation *dp, int flag) 3021static int nfs4_setlease(struct nfs4_delegation *dp)
2944{ 3022{
2945 struct nfs4_file *fp = dp->dl_file; 3023 struct nfs4_file *fp = dp->dl_file;
2946 struct file_lock *fl; 3024 struct file_lock *fl;
2947 int status; 3025 int status;
2948 3026
2949 fl = nfs4_alloc_init_lease(dp, flag); 3027 fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
2950 if (!fl) 3028 if (!fl)
2951 return -ENOMEM; 3029 return -ENOMEM;
2952 fl->fl_file = find_readable_file(fp); 3030 fl->fl_file = find_readable_file(fp);
@@ -2964,12 +3042,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
2964 return 0; 3042 return 0;
2965} 3043}
2966 3044
2967static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) 3045static int nfs4_set_delegation(struct nfs4_delegation *dp)
2968{ 3046{
2969 struct nfs4_file *fp = dp->dl_file; 3047 struct nfs4_file *fp = dp->dl_file;
2970 3048
2971 if (!fp->fi_lease) 3049 if (!fp->fi_lease)
2972 return nfs4_setlease(dp, flag); 3050 return nfs4_setlease(dp);
2973 spin_lock(&recall_lock); 3051 spin_lock(&recall_lock);
2974 if (fp->fi_had_conflict) { 3052 if (fp->fi_had_conflict) {
2975 spin_unlock(&recall_lock); 3053 spin_unlock(&recall_lock);
@@ -3005,6 +3083,9 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
3005 3083
3006/* 3084/*
3007 * Attempt to hand out a delegation. 3085 * Attempt to hand out a delegation.
3086 *
3087 * Note we don't support write delegations, and won't until the vfs has
3088 * proper support for them.
3008 */ 3089 */
3009static void 3090static void
3010nfs4_open_delegation(struct net *net, struct svc_fh *fh, 3091nfs4_open_delegation(struct net *net, struct svc_fh *fh,
@@ -3013,39 +3094,45 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3013 struct nfs4_delegation *dp; 3094 struct nfs4_delegation *dp;
3014 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 3095 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
3015 int cb_up; 3096 int cb_up;
3016 int status = 0, flag = 0; 3097 int status = 0;
3017 3098
3018 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); 3099 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3019 flag = NFS4_OPEN_DELEGATE_NONE;
3020 open->op_recall = 0; 3100 open->op_recall = 0;
3021 switch (open->op_claim_type) { 3101 switch (open->op_claim_type) {
3022 case NFS4_OPEN_CLAIM_PREVIOUS: 3102 case NFS4_OPEN_CLAIM_PREVIOUS:
3023 if (!cb_up) 3103 if (!cb_up)
3024 open->op_recall = 1; 3104 open->op_recall = 1;
3025 flag = open->op_delegate_type; 3105 if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
3026 if (flag == NFS4_OPEN_DELEGATE_NONE) 3106 goto out_no_deleg;
3027 goto out;
3028 break; 3107 break;
3029 case NFS4_OPEN_CLAIM_NULL: 3108 case NFS4_OPEN_CLAIM_NULL:
3030 /* Let's not give out any delegations till everyone's 3109 /*
3031 * had the chance to reclaim theirs.... */ 3110 * Let's not give out any delegations till everyone's
3111 * had the chance to reclaim theirs....
3112 */
3032 if (locks_in_grace(net)) 3113 if (locks_in_grace(net))
3033 goto out; 3114 goto out_no_deleg;
3034 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) 3115 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3035 goto out; 3116 goto out_no_deleg;
3117 /*
3118 * Also, if the file was opened for write or
3119 * create, there's a good chance the client's
3120 * about to write to it, resulting in an
3121 * immediate recall (since we don't support
3122 * write delegations):
3123 */
3036 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 3124 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3037 flag = NFS4_OPEN_DELEGATE_WRITE; 3125 goto out_no_deleg;
3038 else 3126 if (open->op_create == NFS4_OPEN_CREATE)
3039 flag = NFS4_OPEN_DELEGATE_READ; 3127 goto out_no_deleg;
3040 break; 3128 break;
3041 default: 3129 default:
3042 goto out; 3130 goto out_no_deleg;
3043 } 3131 }
3044 3132 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh);
3045 dp = alloc_init_deleg(oo->oo_owner.so_client, stp, fh, flag);
3046 if (dp == NULL) 3133 if (dp == NULL)
3047 goto out_no_deleg; 3134 goto out_no_deleg;
3048 status = nfs4_set_delegation(dp, flag); 3135 status = nfs4_set_delegation(dp);
3049 if (status) 3136 if (status)
3050 goto out_free; 3137 goto out_free;
3051 3138
@@ -3053,24 +3140,23 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3053 3140
3054 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 3141 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3055 STATEID_VAL(&dp->dl_stid.sc_stateid)); 3142 STATEID_VAL(&dp->dl_stid.sc_stateid));
3056out: 3143 open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
3057 open->op_delegate_type = flag;
3058 if (flag == NFS4_OPEN_DELEGATE_NONE) {
3059 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3060 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
3061 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3062
3063 /* 4.1 client asking for a delegation? */
3064 if (open->op_deleg_want)
3065 nfsd4_open_deleg_none_ext(open, status);
3066 }
3067 return; 3144 return;
3068out_free: 3145out_free:
3069 unhash_stid(&dp->dl_stid); 3146 unhash_stid(&dp->dl_stid);
3070 nfs4_put_delegation(dp); 3147 nfs4_put_delegation(dp);
3071out_no_deleg: 3148out_no_deleg:
3072 flag = NFS4_OPEN_DELEGATE_NONE; 3149 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
3073 goto out; 3150 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3151 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3152 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3153 open->op_recall = 1;
3154 }
3155
3156 /* 4.1 client asking for a delegation? */
3157 if (open->op_deleg_want)
3158 nfsd4_open_deleg_none_ext(open, status);
3159 return;
3074} 3160}
3075 3161
3076static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, 3162static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
@@ -3427,7 +3513,7 @@ grace_disallows_io(struct net *net, struct inode *inode)
3427/* Returns true iff a is later than b: */ 3513/* Returns true iff a is later than b: */
3428static bool stateid_generation_after(stateid_t *a, stateid_t *b) 3514static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3429{ 3515{
3430 return (s32)a->si_generation - (s32)b->si_generation > 0; 3516 return (s32)(a->si_generation - b->si_generation) > 0;
3431} 3517}
3432 3518
3433static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3519static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
@@ -4435,7 +4521,6 @@ __be32
4435nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4521nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4436 struct nfsd4_locku *locku) 4522 struct nfsd4_locku *locku)
4437{ 4523{
4438 struct nfs4_lockowner *lo;
4439 struct nfs4_ol_stateid *stp; 4524 struct nfs4_ol_stateid *stp;
4440 struct file *filp = NULL; 4525 struct file *filp = NULL;
4441 struct file_lock *file_lock = NULL; 4526 struct file_lock *file_lock = NULL;
@@ -4468,10 +4553,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4468 status = nfserr_jukebox; 4553 status = nfserr_jukebox;
4469 goto out; 4554 goto out;
4470 } 4555 }
4471 lo = lockowner(stp->st_stateowner);
4472 locks_init_lock(file_lock); 4556 locks_init_lock(file_lock);
4473 file_lock->fl_type = F_UNLCK; 4557 file_lock->fl_type = F_UNLCK;
4474 file_lock->fl_owner = (fl_owner_t)lo; 4558 file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4475 file_lock->fl_pid = current->tgid; 4559 file_lock->fl_pid = current->tgid;
4476 file_lock->fl_file = filp; 4560 file_lock->fl_file = filp;
4477 file_lock->fl_flags = FL_POSIX; 4561 file_lock->fl_flags = FL_POSIX;
@@ -4490,11 +4574,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4490 update_stateid(&stp->st_stid.sc_stateid); 4574 update_stateid(&stp->st_stid.sc_stateid);
4491 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4575 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4492 4576
4493 if (nfsd4_has_session(cstate) && !check_for_locks(stp->st_file, lo)) {
4494 WARN_ON_ONCE(cstate->replay_owner);
4495 release_lockowner(lo);
4496 }
4497
4498out: 4577out:
4499 nfsd4_bump_seqid(cstate, status); 4578 nfsd4_bump_seqid(cstate, status);
4500 if (!cstate->replay_owner) 4579 if (!cstate->replay_owner)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6cd86e0fe450..0c0f3ea90de5 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -55,6 +55,11 @@
55#include "cache.h" 55#include "cache.h"
56#include "netns.h" 56#include "netns.h"
57 57
58#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
59#include <linux/security.h>
60#endif
61
62
58#define NFSDDBG_FACILITY NFSDDBG_XDR 63#define NFSDDBG_FACILITY NFSDDBG_XDR
59 64
60/* 65/*
@@ -134,6 +139,19 @@ xdr_error: \
134 } \ 139 } \
135} while (0) 140} while (0)
136 141
142static void next_decode_page(struct nfsd4_compoundargs *argp)
143{
144 argp->pagelist++;
145 argp->p = page_address(argp->pagelist[0]);
146 if (argp->pagelen < PAGE_SIZE) {
147 argp->end = argp->p + (argp->pagelen>>2);
148 argp->pagelen = 0;
149 } else {
150 argp->end = argp->p + (PAGE_SIZE>>2);
151 argp->pagelen -= PAGE_SIZE;
152 }
153}
154
137static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes) 155static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
138{ 156{
139 /* We want more bytes than seem to be available. 157 /* We want more bytes than seem to be available.
@@ -161,16 +179,7 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
161 * guarantee p points to at least nbytes bytes. 179 * guarantee p points to at least nbytes bytes.
162 */ 180 */
163 memcpy(p, argp->p, avail); 181 memcpy(p, argp->p, avail);
164 /* step to next page */ 182 next_decode_page(argp);
165 argp->p = page_address(argp->pagelist[0]);
166 argp->pagelist++;
167 if (argp->pagelen < PAGE_SIZE) {
168 argp->end = argp->p + (argp->pagelen>>2);
169 argp->pagelen = 0;
170 } else {
171 argp->end = argp->p + (PAGE_SIZE>>2);
172 argp->pagelen -= PAGE_SIZE;
173 }
174 memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); 183 memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
175 argp->p += XDR_QUADLEN(nbytes - avail); 184 argp->p += XDR_QUADLEN(nbytes - avail);
176 return p; 185 return p;
@@ -242,7 +251,8 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
242 251
243static __be32 252static __be32
244nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, 253nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
245 struct iattr *iattr, struct nfs4_acl **acl) 254 struct iattr *iattr, struct nfs4_acl **acl,
255 struct xdr_netobj *label)
246{ 256{
247 int expected_len, len = 0; 257 int expected_len, len = 0;
248 u32 dummy32; 258 u32 dummy32;
@@ -380,6 +390,32 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
380 goto xdr_error; 390 goto xdr_error;
381 } 391 }
382 } 392 }
393
394 label->len = 0;
395#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
396 if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
397 READ_BUF(4);
398 len += 4;
399 READ32(dummy32); /* lfs: we don't use it */
400 READ_BUF(4);
401 len += 4;
402 READ32(dummy32); /* pi: we don't use it either */
403 READ_BUF(4);
404 len += 4;
405 READ32(dummy32);
406 READ_BUF(dummy32);
407 if (dummy32 > NFSD4_MAX_SEC_LABEL_LEN)
408 return nfserr_badlabel;
409 len += (XDR_QUADLEN(dummy32) << 2);
410 READMEM(buf, dummy32);
411 label->data = kzalloc(dummy32 + 1, GFP_KERNEL);
412 if (!label->data)
413 return nfserr_jukebox;
414 defer_free(argp, kfree, label->data);
415 memcpy(label->data, buf, dummy32);
416 }
417#endif
418
383 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0 419 if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
384 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1 420 || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
385 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) 421 || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
@@ -428,7 +464,11 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
428 /* callback_sec_params4 */ 464 /* callback_sec_params4 */
429 READ_BUF(4); 465 READ_BUF(4);
430 READ32(nr_secflavs); 466 READ32(nr_secflavs);
431 cbs->flavor = (u32)(-1); 467 if (nr_secflavs)
468 cbs->flavor = (u32)(-1);
469 else
470 /* Is this legal? Be generous, take it to mean AUTH_NONE: */
471 cbs->flavor = 0;
432 for (i = 0; i < nr_secflavs; ++i) { 472 for (i = 0; i < nr_secflavs; ++i) {
433 READ_BUF(4); 473 READ_BUF(4);
434 READ32(dummy); 474 READ32(dummy);
@@ -576,7 +616,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
576 return status; 616 return status;
577 617
578 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr, 618 status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
579 &create->cr_acl); 619 &create->cr_acl, &create->cr_label);
580 if (status) 620 if (status)
581 goto out; 621 goto out;
582 622
@@ -827,7 +867,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
827 case NFS4_CREATE_UNCHECKED: 867 case NFS4_CREATE_UNCHECKED:
828 case NFS4_CREATE_GUARDED: 868 case NFS4_CREATE_GUARDED:
829 status = nfsd4_decode_fattr(argp, open->op_bmval, 869 status = nfsd4_decode_fattr(argp, open->op_bmval,
830 &open->op_iattr, &open->op_acl); 870 &open->op_iattr, &open->op_acl, &open->op_label);
831 if (status) 871 if (status)
832 goto out; 872 goto out;
833 break; 873 break;
@@ -841,7 +881,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
841 READ_BUF(NFS4_VERIFIER_SIZE); 881 READ_BUF(NFS4_VERIFIER_SIZE);
842 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE); 882 COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
843 status = nfsd4_decode_fattr(argp, open->op_bmval, 883 status = nfsd4_decode_fattr(argp, open->op_bmval,
844 &open->op_iattr, &open->op_acl); 884 &open->op_iattr, &open->op_acl, &open->op_label);
845 if (status) 885 if (status)
846 goto out; 886 goto out;
847 break; 887 break;
@@ -1063,7 +1103,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
1063 if (status) 1103 if (status)
1064 return status; 1104 return status;
1065 return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr, 1105 return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
1066 &setattr->sa_acl); 1106 &setattr->sa_acl, &setattr->sa_label);
1067} 1107}
1068 1108
1069static __be32 1109static __be32
@@ -1567,6 +1607,7 @@ struct nfsd4_minorversion_ops {
1567static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { 1607static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
1568 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, 1608 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
1569 [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, 1609 [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
1610 [2] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
1570}; 1611};
1571 1612
1572static __be32 1613static __be32
@@ -1953,6 +1994,36 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
1953 FATTR4_WORD0_RDATTR_ERROR) 1994 FATTR4_WORD0_RDATTR_ERROR)
1954#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID 1995#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
1955 1996
1997#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
1998static inline __be32
1999nfsd4_encode_security_label(struct svc_rqst *rqstp, void *context, int len, __be32 **pp, int *buflen)
2000{
2001 __be32 *p = *pp;
2002
2003 if (*buflen < ((XDR_QUADLEN(len) << 2) + 4 + 4 + 4))
2004 return nfserr_resource;
2005
2006 /*
2007 * For now we use a 0 here to indicate the null translation; in
2008 * the future we may place a call to translation code here.
2009 */
2010 if ((*buflen -= 8) < 0)
2011 return nfserr_resource;
2012
2013 WRITE32(0); /* lfs */
2014 WRITE32(0); /* pi */
2015 p = xdr_encode_opaque(p, context, len);
2016 *buflen -= (XDR_QUADLEN(len) << 2) + 4;
2017
2018 *pp = p;
2019 return 0;
2020}
2021#else
2022static inline __be32
2023nfsd4_encode_security_label(struct svc_rqst *rqstp, void *context, int len, __be32 **pp, int *buflen)
2024{ return 0; }
2025#endif
2026
1956static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) 2027static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1957{ 2028{
1958 /* As per referral draft: */ 2029 /* As per referral draft: */
@@ -2012,6 +2083,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2012 int err; 2083 int err;
2013 int aclsupport = 0; 2084 int aclsupport = 0;
2014 struct nfs4_acl *acl = NULL; 2085 struct nfs4_acl *acl = NULL;
2086 void *context = NULL;
2087 int contextlen;
2088 bool contextsupport = false;
2015 struct nfsd4_compoundres *resp = rqstp->rq_resp; 2089 struct nfsd4_compoundres *resp = rqstp->rq_resp;
2016 u32 minorversion = resp->cstate.minorversion; 2090 u32 minorversion = resp->cstate.minorversion;
2017 struct path path = { 2091 struct path path = {
@@ -2065,6 +2139,21 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2065 } 2139 }
2066 } 2140 }
2067 2141
2142#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2143 if ((bmval[2] & FATTR4_WORD2_SECURITY_LABEL) ||
2144 bmval[0] & FATTR4_WORD0_SUPPORTED_ATTRS) {
2145 err = security_inode_getsecctx(dentry->d_inode,
2146 &context, &contextlen);
2147 contextsupport = (err == 0);
2148 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2149 if (err == -EOPNOTSUPP)
2150 bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2151 else if (err)
2152 goto out_nfserr;
2153 }
2154 }
2155#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2156
2068 if (bmval2) { 2157 if (bmval2) {
2069 if ((buflen -= 16) < 0) 2158 if ((buflen -= 16) < 0)
2070 goto out_resource; 2159 goto out_resource;
@@ -2093,6 +2182,8 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2093 2182
2094 if (!aclsupport) 2183 if (!aclsupport)
2095 word0 &= ~FATTR4_WORD0_ACL; 2184 word0 &= ~FATTR4_WORD0_ACL;
2185 if (!contextsupport)
2186 word2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2096 if (!word2) { 2187 if (!word2) {
2097 if ((buflen -= 12) < 0) 2188 if ((buflen -= 12) < 0)
2098 goto out_resource; 2189 goto out_resource;
@@ -2400,6 +2491,12 @@ out_acl:
2400 get_parent_attributes(exp, &stat); 2491 get_parent_attributes(exp, &stat);
2401 WRITE64(stat.ino); 2492 WRITE64(stat.ino);
2402 } 2493 }
2494 if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2495 status = nfsd4_encode_security_label(rqstp, context,
2496 contextlen, &p, &buflen);
2497 if (status)
2498 goto out;
2499 }
2403 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { 2500 if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2404 WRITE32(3); 2501 WRITE32(3);
2405 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); 2502 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
@@ -2412,6 +2509,10 @@ out_acl:
2412 status = nfs_ok; 2509 status = nfs_ok;
2413 2510
2414out: 2511out:
2512#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2513 if (context)
2514 security_release_secctx(context, contextlen);
2515#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2415 kfree(acl); 2516 kfree(acl);
2416 if (fhp == &tempfh) 2517 if (fhp == &tempfh)
2417 fh_put(&tempfh); 2518 fh_put(&tempfh);
@@ -3176,16 +3277,18 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3176{ 3277{
3177 __be32 *p; 3278 __be32 *p;
3178 3279
3179 RESERVE_SPACE(12); 3280 RESERVE_SPACE(16);
3180 if (nfserr) { 3281 if (nfserr) {
3181 WRITE32(2); 3282 WRITE32(3);
3283 WRITE32(0);
3182 WRITE32(0); 3284 WRITE32(0);
3183 WRITE32(0); 3285 WRITE32(0);
3184 } 3286 }
3185 else { 3287 else {
3186 WRITE32(2); 3288 WRITE32(3);
3187 WRITE32(setattr->sa_bmval[0]); 3289 WRITE32(setattr->sa_bmval[0]);
3188 WRITE32(setattr->sa_bmval[1]); 3290 WRITE32(setattr->sa_bmval[1]);
3291 WRITE32(setattr->sa_bmval[2]);
3189 } 3292 }
3190 ADJUST_ARGS(); 3293 ADJUST_ARGS();
3191 return nfserr; 3294 return nfserr;
@@ -3226,6 +3329,14 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
3226 return nfserr; 3329 return nfserr;
3227} 3330}
3228 3331
3332static const u32 nfs4_minimal_spo_must_enforce[2] = {
3333 [1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
3334 1 << (OP_EXCHANGE_ID - 32) |
3335 1 << (OP_CREATE_SESSION - 32) |
3336 1 << (OP_DESTROY_SESSION - 32) |
3337 1 << (OP_DESTROY_CLIENTID - 32)
3338};
3339
3229static __be32 3340static __be32
3230nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, 3341nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3231 struct nfsd4_exchange_id *exid) 3342 struct nfsd4_exchange_id *exid)
@@ -3264,6 +3375,20 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3264 /* state_protect4_r. Currently only support SP4_NONE */ 3375 /* state_protect4_r. Currently only support SP4_NONE */
3265 BUG_ON(exid->spa_how != SP4_NONE); 3376 BUG_ON(exid->spa_how != SP4_NONE);
3266 WRITE32(exid->spa_how); 3377 WRITE32(exid->spa_how);
3378 switch (exid->spa_how) {
3379 case SP4_NONE:
3380 break;
3381 case SP4_MACH_CRED:
3382 /* spo_must_enforce bitmap: */
3383 WRITE32(2);
3384 WRITE32(nfs4_minimal_spo_must_enforce[0]);
3385 WRITE32(nfs4_minimal_spo_must_enforce[1]);
3386 /* empty spo_must_allow bitmap: */
3387 WRITE32(0);
3388 break;
3389 default:
3390 WARN_ON_ONCE(1);
3391 }
3267 3392
3268 /* The server_owner struct */ 3393 /* The server_owner struct */
3269 WRITE64(minor_id); /* Minor id */ 3394 WRITE64(minor_id); /* Minor id */
@@ -3635,13 +3760,17 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
3635 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; 3760 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3636 BUG_ON(iov->iov_len > PAGE_SIZE); 3761 BUG_ON(iov->iov_len > PAGE_SIZE);
3637 if (nfsd4_has_session(cs)) { 3762 if (nfsd4_has_session(cs)) {
3763 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3764 struct nfs4_client *clp = cs->session->se_client;
3638 if (cs->status != nfserr_replay_cache) { 3765 if (cs->status != nfserr_replay_cache) {
3639 nfsd4_store_cache_entry(resp); 3766 nfsd4_store_cache_entry(resp);
3640 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE; 3767 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
3641 } 3768 }
3642 /* Renew the clientid on success and on replay */ 3769 /* Renew the clientid on success and on replay */
3643 put_client_renew(cs->session->se_client); 3770 spin_lock(&nn->client_lock);
3644 nfsd4_put_session(cs->session); 3771 nfsd4_put_session(cs->session);
3772 spin_unlock(&nn->client_lock);
3773 put_client_renew(clp);
3645 } 3774 }
3646 return 1; 3775 return 1;
3647} 3776}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index c0d93170585d..2bbd94e51efc 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -24,7 +24,7 @@
24/* 24/*
25 * nfsd version 25 * nfsd version
26 */ 26 */
27#define NFSD_SUPPORTED_MINOR_VERSION 1 27#define NFSD_SUPPORTED_MINOR_VERSION 2
28/* 28/*
29 * Maximum blocksizes supported by daemon under various circumstances. 29 * Maximum blocksizes supported by daemon under various circumstances.
30 */ 30 */
@@ -328,6 +328,13 @@ void nfsd_lockd_shutdown(void);
328#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ 328#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \
329 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) 329 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
330 330
331#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
332#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
333 (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL)
334#else
335#define NFSD4_2_SUPPORTED_ATTRS_WORD2 0
336#endif
337
331static inline u32 nfsd_suppattrs0(u32 minorversion) 338static inline u32 nfsd_suppattrs0(u32 minorversion)
332{ 339{
333 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 340 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
@@ -342,8 +349,11 @@ static inline u32 nfsd_suppattrs1(u32 minorversion)
342 349
343static inline u32 nfsd_suppattrs2(u32 minorversion) 350static inline u32 nfsd_suppattrs2(u32 minorversion)
344{ 351{
345 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2 352 switch (minorversion) {
346 : NFSD4_SUPPORTED_ATTRS_WORD2; 353 default: return NFSD4_2_SUPPORTED_ATTRS_WORD2;
354 case 1: return NFSD4_1_SUPPORTED_ATTRS_WORD2;
355 case 0: return NFSD4_SUPPORTED_ATTRS_WORD2;
356 }
347} 357}
348 358
349/* These will return ERR_INVAL if specified in GETATTR or READDIR. */ 359/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
@@ -356,7 +366,11 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
356#define NFSD_WRITEABLE_ATTRS_WORD1 \ 366#define NFSD_WRITEABLE_ATTRS_WORD1 \
357 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ 367 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
358 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) 368 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
369#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
370#define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL
371#else
359#define NFSD_WRITEABLE_ATTRS_WORD2 0 372#define NFSD_WRITEABLE_ATTRS_WORD2 0
373#endif
360 374
361#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ 375#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
362 NFSD_WRITEABLE_ATTRS_WORD0 376 NFSD_WRITEABLE_ATTRS_WORD0
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 262df5ccbf59..6b9f48ca4c25 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -116,7 +116,7 @@ struct svc_program nfsd_program = {
116 116
117}; 117};
118 118
119u32 nfsd_supported_minorversion; 119u32 nfsd_supported_minorversion = 1;
120 120
121int nfsd_vers(int vers, enum vers_op change) 121int nfsd_vers(int vers, enum vers_op change)
122{ 122{
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 274e2a114e05..424d8f5f2317 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -246,6 +246,7 @@ struct nfs4_client {
246 nfs4_verifier cl_verifier; /* generated by client */ 246 nfs4_verifier cl_verifier; /* generated by client */
247 time_t cl_time; /* time of last lease renewal */ 247 time_t cl_time; /* time of last lease renewal */
248 struct sockaddr_storage cl_addr; /* client ipaddress */ 248 struct sockaddr_storage cl_addr; /* client ipaddress */
249 bool cl_mach_cred; /* SP4_MACH_CRED in force */
249 struct svc_cred cl_cred; /* setclientid principal */ 250 struct svc_cred cl_cred; /* setclientid principal */
250 clientid_t cl_clientid; /* generated by server */ 251 clientid_t cl_clientid; /* generated by server */
251 nfs4_verifier cl_confirm; /* generated by server */ 252 nfs4_verifier cl_confirm; /* generated by server */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index a6bc8a7423db..8ff6a0019b0b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -28,6 +28,7 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <linux/exportfs.h> 29#include <linux/exportfs.h>
30#include <linux/writeback.h> 30#include <linux/writeback.h>
31#include <linux/security.h>
31 32
32#ifdef CONFIG_NFSD_V3 33#ifdef CONFIG_NFSD_V3
33#include "xdr3.h" 34#include "xdr3.h"
@@ -621,6 +622,33 @@ int nfsd4_is_junction(struct dentry *dentry)
621 return 0; 622 return 0;
622 return 1; 623 return 1;
623} 624}
625#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
626__be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
627 struct xdr_netobj *label)
628{
629 __be32 error;
630 int host_error;
631 struct dentry *dentry;
632
633 error = fh_verify(rqstp, fhp, 0 /* S_IFREG */, NFSD_MAY_SATTR);
634 if (error)
635 return error;
636
637 dentry = fhp->fh_dentry;
638
639 mutex_lock(&dentry->d_inode->i_mutex);
640 host_error = security_inode_setsecctx(dentry, label->data, label->len);
641 mutex_unlock(&dentry->d_inode->i_mutex);
642 return nfserrno(host_error);
643}
644#else
645__be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
646 struct xdr_netobj *label)
647{
648 return nfserr_notsupp;
649}
650#endif
651
624#endif /* defined(CONFIG_NFSD_V4) */ 652#endif /* defined(CONFIG_NFSD_V4) */
625 653
626#ifdef CONFIG_NFSD_V3 654#ifdef CONFIG_NFSD_V3
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 5b5894159f22..a4be2e389670 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -39,7 +39,6 @@
39typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); 39typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
40 40
41/* nfsd/vfs.c */ 41/* nfsd/vfs.c */
42int fh_lock_parent(struct svc_fh *, struct dentry *);
43int nfsd_racache_init(int); 42int nfsd_racache_init(int);
44void nfsd_racache_shutdown(void); 43void nfsd_racache_shutdown(void);
45int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 44int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
@@ -56,6 +55,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *);
56__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, 55__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
57 struct nfs4_acl *); 56 struct nfs4_acl *);
58int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); 57int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
58__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
59 struct xdr_netobj *);
59#endif /* CONFIG_NFSD_V4 */ 60#endif /* CONFIG_NFSD_V4 */
60__be32 nfsd_create(struct svc_rqst *, struct svc_fh *, 61__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
61 char *name, int len, struct iattr *attrs, 62 char *name, int len, struct iattr *attrs,
@@ -92,17 +93,13 @@ __be32 nfsd_remove(struct svc_rqst *,
92 struct svc_fh *, char *, int); 93 struct svc_fh *, char *, int);
93__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, 94__be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
94 char *name, int len); 95 char *name, int len);
95int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
96 unsigned long size);
97__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, 96__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
98 loff_t *, struct readdir_cd *, filldir_t); 97 loff_t *, struct readdir_cd *, filldir_t);
99__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, 98__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
100 struct kstatfs *, int access); 99 struct kstatfs *, int access);
101 100
102int nfsd_notify_change(struct inode *, struct iattr *);
103__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, 101__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
104 struct dentry *, int); 102 struct dentry *, int);
105int nfsd_sync_dir(struct dentry *dp);
106 103
107#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 104#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
108struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); 105struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 3b271d2092b6..b3ed6446ed8e 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -40,6 +40,7 @@
40#include "state.h" 40#include "state.h"
41#include "nfsd.h" 41#include "nfsd.h"
42 42
43#define NFSD4_MAX_SEC_LABEL_LEN 2048
43#define NFSD4_MAX_TAGLEN 128 44#define NFSD4_MAX_TAGLEN 128
44#define XDR_LEN(n) (((n) + 3) & ~3) 45#define XDR_LEN(n) (((n) + 3) & ~3)
45 46
@@ -118,6 +119,7 @@ struct nfsd4_create {
118 struct iattr cr_iattr; /* request */ 119 struct iattr cr_iattr; /* request */
119 struct nfsd4_change_info cr_cinfo; /* response */ 120 struct nfsd4_change_info cr_cinfo; /* response */
120 struct nfs4_acl *cr_acl; 121 struct nfs4_acl *cr_acl;
122 struct xdr_netobj cr_label;
121}; 123};
122#define cr_linklen u.link.namelen 124#define cr_linklen u.link.namelen
123#define cr_linkname u.link.name 125#define cr_linkname u.link.name
@@ -246,6 +248,7 @@ struct nfsd4_open {
246 struct nfs4_file *op_file; /* used during processing */ 248 struct nfs4_file *op_file; /* used during processing */
247 struct nfs4_ol_stateid *op_stp; /* used during processing */ 249 struct nfs4_ol_stateid *op_stp; /* used during processing */
248 struct nfs4_acl *op_acl; 250 struct nfs4_acl *op_acl;
251 struct xdr_netobj op_label;
249}; 252};
250#define op_iattr iattr 253#define op_iattr iattr
251 254
@@ -330,6 +333,7 @@ struct nfsd4_setattr {
330 u32 sa_bmval[3]; /* request */ 333 u32 sa_bmval[3]; /* request */
331 struct iattr sa_iattr; /* request */ 334 struct iattr sa_iattr; /* request */
332 struct nfs4_acl *sa_acl; 335 struct nfs4_acl *sa_acl;
336 struct xdr_netobj sa_label;
333}; 337};
334 338
335struct nfsd4_setclientid { 339struct nfsd4_setclientid {
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 303399b1ba59..6ce690de447f 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -57,6 +57,7 @@ struct cache_head {
57#define CACHE_VALID 0 /* Entry contains valid data */ 57#define CACHE_VALID 0 /* Entry contains valid data */
58#define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */ 58#define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */
59#define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/ 59#define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/
60#define CACHE_CLEANED 3 /* Entry has been cleaned from cache */
60 61
61#define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */ 62#define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */
62 63
@@ -148,6 +149,24 @@ struct cache_deferred_req {
148 int too_many); 149 int too_many);
149}; 150};
150 151
152/*
153 * timestamps kept in the cache are expressed in seconds
154 * since boot. This is the best for measuring differences in
155 * real time.
156 */
157static inline time_t seconds_since_boot(void)
158{
159 struct timespec boot;
160 getboottime(&boot);
161 return get_seconds() - boot.tv_sec;
162}
163
164static inline time_t convert_to_wallclock(time_t sinceboot)
165{
166 struct timespec boot;
167 getboottime(&boot);
168 return boot.tv_sec + sinceboot;
169}
151 170
152extern const struct file_operations cache_file_operations_pipefs; 171extern const struct file_operations cache_file_operations_pipefs;
153extern const struct file_operations content_file_operations_pipefs; 172extern const struct file_operations content_file_operations_pipefs;
@@ -181,15 +200,10 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
181 kref_put(&h->ref, cd->cache_put); 200 kref_put(&h->ref, cd->cache_put);
182} 201}
183 202
184static inline int cache_valid(struct cache_head *h) 203static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
185{ 204{
186 /* If an item has been unhashed pending removal when 205 return (h->expiry_time < seconds_since_boot()) ||
187 * the refcount drops to 0, the expiry_time will be 206 (detail->flush_time > h->last_refresh);
188 * set to 0. We don't want to consider such items
189 * valid in this context even though CACHE_VALID is
190 * set.
191 */
192 return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags));
193} 207}
194 208
195extern int cache_check(struct cache_detail *detail, 209extern int cache_check(struct cache_detail *detail,
@@ -250,25 +264,6 @@ static inline int get_uint(char **bpp, unsigned int *anint)
250 return 0; 264 return 0;
251} 265}
252 266
253/*
254 * timestamps kept in the cache are expressed in seconds
255 * since boot. This is the best for measuring differences in
256 * real time.
257 */
258static inline time_t seconds_since_boot(void)
259{
260 struct timespec boot;
261 getboottime(&boot);
262 return get_seconds() - boot.tv_sec;
263}
264
265static inline time_t convert_to_wallclock(time_t sinceboot)
266{
267 struct timespec boot;
268 getboottime(&boot);
269 return boot.tv_sec + sinceboot;
270}
271
272static inline time_t get_expiry(char **bpp) 267static inline time_t get_expiry(char **bpp)
273{ 268{
274 int rv; 269 int rv;
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index 161463e59624..1f911ccb2a75 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -151,6 +151,8 @@ struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
151/* Fill in an array with a list of supported pseudoflavors */ 151/* Fill in an array with a list of supported pseudoflavors */
152int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int); 152int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int);
153 153
154struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
155
154/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a 156/* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
155 * corresponding call to gss_mech_put. */ 157 * corresponding call to gss_mech_put. */
156void gss_mech_put(struct gss_api_mech *); 158void gss_mech_put(struct gss_api_mech *);
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index ff374ab30839..8d71d6577459 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -14,6 +14,7 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/sunrpc/msg_prot.h> 15#include <linux/sunrpc/msg_prot.h>
16#include <linux/sunrpc/cache.h> 16#include <linux/sunrpc/cache.h>
17#include <linux/sunrpc/gss_api.h>
17#include <linux/hash.h> 18#include <linux/hash.h>
18#include <linux/cred.h> 19#include <linux/cred.h>
19 20
@@ -23,13 +24,23 @@ struct svc_cred {
23 struct group_info *cr_group_info; 24 struct group_info *cr_group_info;
24 u32 cr_flavor; /* pseudoflavor */ 25 u32 cr_flavor; /* pseudoflavor */
25 char *cr_principal; /* for gss */ 26 char *cr_principal; /* for gss */
27 struct gss_api_mech *cr_gss_mech;
26}; 28};
27 29
30static inline void init_svc_cred(struct svc_cred *cred)
31{
32 cred->cr_group_info = NULL;
33 cred->cr_principal = NULL;
34 cred->cr_gss_mech = NULL;
35}
36
28static inline void free_svc_cred(struct svc_cred *cred) 37static inline void free_svc_cred(struct svc_cred *cred)
29{ 38{
30 if (cred->cr_group_info) 39 if (cred->cr_group_info)
31 put_group_info(cred->cr_group_info); 40 put_group_info(cred->cr_group_info);
32 kfree(cred->cr_principal); 41 kfree(cred->cr_principal);
42 gss_mech_put(cred->cr_gss_mech);
43 init_svc_cred(cred);
33} 44}
34 45
35struct svc_rqst; /* forward decl */ 46struct svc_rqst; /* forward decl */
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index defa9d33925c..27ce26240932 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -139,11 +139,12 @@ void gss_mech_unregister(struct gss_api_mech *gm)
139} 139}
140EXPORT_SYMBOL_GPL(gss_mech_unregister); 140EXPORT_SYMBOL_GPL(gss_mech_unregister);
141 141
142static struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm) 142struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm)
143{ 143{
144 __module_get(gm->gm_owner); 144 __module_get(gm->gm_owner);
145 return gm; 145 return gm;
146} 146}
147EXPORT_SYMBOL(gss_mech_get);
147 148
148static struct gss_api_mech * 149static struct gss_api_mech *
149_gss_mech_get_by_name(const char *name) 150_gss_mech_get_by_name(const char *name)
@@ -360,6 +361,7 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
360 } 361 }
361 return 0; 362 return 0;
362} 363}
364EXPORT_SYMBOL(gss_pseudoflavor_to_service);
363 365
364char * 366char *
365gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) 367gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
@@ -379,6 +381,7 @@ gss_mech_put(struct gss_api_mech * gm)
379 if (gm) 381 if (gm)
380 module_put(gm->gm_owner); 382 module_put(gm->gm_owner);
381} 383}
384EXPORT_SYMBOL(gss_mech_put);
382 385
383/* The mech could probably be determined from the token instead, but it's just 386/* The mech could probably be determined from the token instead, but it's just
384 * as easy for now to pass it in. */ 387 * as easy for now to pass it in. */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index b05ace4c5f12..d0347d148b34 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -377,8 +377,7 @@ rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
377 new->handle.data = tmp->handle.data; 377 new->handle.data = tmp->handle.data;
378 tmp->handle.data = NULL; 378 tmp->handle.data = NULL;
379 new->mechctx = NULL; 379 new->mechctx = NULL;
380 new->cred.cr_group_info = NULL; 380 init_svc_cred(&new->cred);
381 new->cred.cr_principal = NULL;
382} 381}
383 382
384static void 383static void
@@ -392,9 +391,7 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
392 memset(&new->seqdata, 0, sizeof(new->seqdata)); 391 memset(&new->seqdata, 0, sizeof(new->seqdata));
393 spin_lock_init(&new->seqdata.sd_lock); 392 spin_lock_init(&new->seqdata.sd_lock);
394 new->cred = tmp->cred; 393 new->cred = tmp->cred;
395 tmp->cred.cr_group_info = NULL; 394 init_svc_cred(&tmp->cred);
396 new->cred.cr_principal = tmp->cred.cr_principal;
397 tmp->cred.cr_principal = NULL;
398} 395}
399 396
400static struct cache_head * 397static struct cache_head *
@@ -487,7 +484,7 @@ static int rsc_parse(struct cache_detail *cd,
487 len = qword_get(&mesg, buf, mlen); 484 len = qword_get(&mesg, buf, mlen);
488 if (len < 0) 485 if (len < 0)
489 goto out; 486 goto out;
490 gm = gss_mech_get_by_name(buf); 487 gm = rsci.cred.cr_gss_mech = gss_mech_get_by_name(buf);
491 status = -EOPNOTSUPP; 488 status = -EOPNOTSUPP;
492 if (!gm) 489 if (!gm)
493 goto out; 490 goto out;
@@ -517,7 +514,6 @@ static int rsc_parse(struct cache_detail *cd,
517 rscp = rsc_update(cd, &rsci, rscp); 514 rscp = rsc_update(cd, &rsci, rscp);
518 status = 0; 515 status = 0;
519out: 516out:
520 gss_mech_put(gm);
521 rsc_free(&rsci); 517 rsc_free(&rsci);
522 if (rscp) 518 if (rscp)
523 cache_put(&rscp->h, cd); 519 cache_put(&rscp->h, cd);
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 80fe5c86efd1..49eb37010aa3 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -50,12 +50,6 @@ static void cache_init(struct cache_head *h)
50 h->last_refresh = now; 50 h->last_refresh = now;
51} 51}
52 52
53static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
54{
55 return (h->expiry_time < seconds_since_boot()) ||
56 (detail->flush_time > h->last_refresh);
57}
58
59struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, 53struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
60 struct cache_head *key, int hash) 54 struct cache_head *key, int hash)
61{ 55{
@@ -201,7 +195,7 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
201 return sunrpc_cache_pipe_upcall(cd, h); 195 return sunrpc_cache_pipe_upcall(cd, h);
202} 196}
203 197
204static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h) 198static inline int cache_is_valid(struct cache_head *h)
205{ 199{
206 if (!test_bit(CACHE_VALID, &h->flags)) 200 if (!test_bit(CACHE_VALID, &h->flags))
207 return -EAGAIN; 201 return -EAGAIN;
@@ -227,16 +221,15 @@ static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h
227 int rv; 221 int rv;
228 222
229 write_lock(&detail->hash_lock); 223 write_lock(&detail->hash_lock);
230 rv = cache_is_valid(detail, h); 224 rv = cache_is_valid(h);
231 if (rv != -EAGAIN) { 225 if (rv == -EAGAIN) {
232 write_unlock(&detail->hash_lock); 226 set_bit(CACHE_NEGATIVE, &h->flags);
233 return rv; 227 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
228 rv = -ENOENT;
234 } 229 }
235 set_bit(CACHE_NEGATIVE, &h->flags);
236 cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
237 write_unlock(&detail->hash_lock); 230 write_unlock(&detail->hash_lock);
238 cache_fresh_unlocked(h, detail); 231 cache_fresh_unlocked(h, detail);
239 return -ENOENT; 232 return rv;
240} 233}
241 234
242/* 235/*
@@ -260,7 +253,7 @@ int cache_check(struct cache_detail *detail,
260 long refresh_age, age; 253 long refresh_age, age;
261 254
262 /* First decide return status as best we can */ 255 /* First decide return status as best we can */
263 rv = cache_is_valid(detail, h); 256 rv = cache_is_valid(h);
264 257
265 /* now see if we want to start an upcall */ 258 /* now see if we want to start an upcall */
266 refresh_age = (h->expiry_time - h->last_refresh); 259 refresh_age = (h->expiry_time - h->last_refresh);
@@ -269,19 +262,17 @@ int cache_check(struct cache_detail *detail,
269 if (rqstp == NULL) { 262 if (rqstp == NULL) {
270 if (rv == -EAGAIN) 263 if (rv == -EAGAIN)
271 rv = -ENOENT; 264 rv = -ENOENT;
272 } else if (rv == -EAGAIN || age > refresh_age/2) { 265 } else if (rv == -EAGAIN ||
266 (h->expiry_time != 0 && age > refresh_age/2)) {
273 dprintk("RPC: Want update, refage=%ld, age=%ld\n", 267 dprintk("RPC: Want update, refage=%ld, age=%ld\n",
274 refresh_age, age); 268 refresh_age, age);
275 if (!test_and_set_bit(CACHE_PENDING, &h->flags)) { 269 if (!test_and_set_bit(CACHE_PENDING, &h->flags)) {
276 switch (cache_make_upcall(detail, h)) { 270 switch (cache_make_upcall(detail, h)) {
277 case -EINVAL: 271 case -EINVAL:
278 clear_bit(CACHE_PENDING, &h->flags);
279 cache_revisit_request(h);
280 rv = try_to_negate_entry(detail, h); 272 rv = try_to_negate_entry(detail, h);
281 break; 273 break;
282 case -EAGAIN: 274 case -EAGAIN:
283 clear_bit(CACHE_PENDING, &h->flags); 275 cache_fresh_unlocked(h, detail);
284 cache_revisit_request(h);
285 break; 276 break;
286 } 277 }
287 } 278 }
@@ -293,7 +284,7 @@ int cache_check(struct cache_detail *detail,
293 * Request was not deferred; handle it as best 284 * Request was not deferred; handle it as best
294 * we can ourselves: 285 * we can ourselves:
295 */ 286 */
296 rv = cache_is_valid(detail, h); 287 rv = cache_is_valid(h);
297 if (rv == -EAGAIN) 288 if (rv == -EAGAIN)
298 rv = -ETIMEDOUT; 289 rv = -ETIMEDOUT;
299 } 290 }
@@ -310,7 +301,7 @@ EXPORT_SYMBOL_GPL(cache_check);
310 * a current pointer into that list and into the table 301 * a current pointer into that list and into the table
311 * for that entry. 302 * for that entry.
312 * 303 *
313 * Each time clean_cache is called it finds the next non-empty entry 304 * Each time cache_clean is called it finds the next non-empty entry
314 * in the current table and walks the list in that entry 305 * in the current table and walks the list in that entry
315 * looking for entries that can be removed. 306 * looking for entries that can be removed.
316 * 307 *
@@ -457,9 +448,8 @@ static int cache_clean(void)
457 current_index ++; 448 current_index ++;
458 spin_unlock(&cache_list_lock); 449 spin_unlock(&cache_list_lock);
459 if (ch) { 450 if (ch) {
460 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 451 set_bit(CACHE_CLEANED, &ch->flags);
461 cache_dequeue(current_detail, ch); 452 cache_fresh_unlocked(ch, d);
462 cache_revisit_request(ch);
463 cache_put(ch, d); 453 cache_put(ch, d);
464 } 454 }
465 } else 455 } else
@@ -1036,23 +1026,32 @@ static int cache_release(struct inode *inode, struct file *filp,
1036 1026
1037static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch) 1027static void cache_dequeue(struct cache_detail *detail, struct cache_head *ch)
1038{ 1028{
1039 struct cache_queue *cq; 1029 struct cache_queue *cq, *tmp;
1030 struct cache_request *cr;
1031 struct list_head dequeued;
1032
1033 INIT_LIST_HEAD(&dequeued);
1040 spin_lock(&queue_lock); 1034 spin_lock(&queue_lock);
1041 list_for_each_entry(cq, &detail->queue, list) 1035 list_for_each_entry_safe(cq, tmp, &detail->queue, list)
1042 if (!cq->reader) { 1036 if (!cq->reader) {
1043 struct cache_request *cr = container_of(cq, struct cache_request, q); 1037 cr = container_of(cq, struct cache_request, q);
1044 if (cr->item != ch) 1038 if (cr->item != ch)
1045 continue; 1039 continue;
1040 if (test_bit(CACHE_PENDING, &ch->flags))
1041 /* Lost a race and it is pending again */
1042 break;
1046 if (cr->readers != 0) 1043 if (cr->readers != 0)
1047 continue; 1044 continue;
1048 list_del(&cr->q.list); 1045 list_move(&cr->q.list, &dequeued);
1049 spin_unlock(&queue_lock);
1050 cache_put(cr->item, detail);
1051 kfree(cr->buf);
1052 kfree(cr);
1053 return;
1054 } 1046 }
1055 spin_unlock(&queue_lock); 1047 spin_unlock(&queue_lock);
1048 while (!list_empty(&dequeued)) {
1049 cr = list_entry(dequeued.next, struct cache_request, q.list);
1050 list_del(&cr->q.list);
1051 cache_put(cr->item, detail);
1052 kfree(cr->buf);
1053 kfree(cr);
1054 }
1056} 1055}
1057 1056
1058/* 1057/*
@@ -1166,6 +1165,7 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h)
1166 1165
1167 char *buf; 1166 char *buf;
1168 struct cache_request *crq; 1167 struct cache_request *crq;
1168 int ret = 0;
1169 1169
1170 if (!detail->cache_request) 1170 if (!detail->cache_request)
1171 return -EINVAL; 1171 return -EINVAL;
@@ -1174,6 +1174,9 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h)
1174 warn_no_listener(detail); 1174 warn_no_listener(detail);
1175 return -EINVAL; 1175 return -EINVAL;
1176 } 1176 }
1177 if (test_bit(CACHE_CLEANED, &h->flags))
1178 /* Too late to make an upcall */
1179 return -EAGAIN;
1177 1180
1178 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 1181 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1179 if (!buf) 1182 if (!buf)
@@ -1191,10 +1194,18 @@ int sunrpc_cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h)
1191 crq->len = 0; 1194 crq->len = 0;
1192 crq->readers = 0; 1195 crq->readers = 0;
1193 spin_lock(&queue_lock); 1196 spin_lock(&queue_lock);
1194 list_add_tail(&crq->q.list, &detail->queue); 1197 if (test_bit(CACHE_PENDING, &h->flags))
1198 list_add_tail(&crq->q.list, &detail->queue);
1199 else
1200 /* Lost a race, no longer PENDING, so don't enqueue */
1201 ret = -EAGAIN;
1195 spin_unlock(&queue_lock); 1202 spin_unlock(&queue_lock);
1196 wake_up(&queue_wait); 1203 wake_up(&queue_wait);
1197 return 0; 1204 if (ret == -EAGAIN) {
1205 kfree(buf);
1206 kfree(crq);
1207 }
1208 return ret;
1198} 1209}
1199EXPORT_SYMBOL_GPL(sunrpc_cache_pipe_upcall); 1210EXPORT_SYMBOL_GPL(sunrpc_cache_pipe_upcall);
1200 1211
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 06bdf5a1082c..621ca7b4a155 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -347,13 +347,13 @@ ip_map_cached_get(struct svc_xprt *xprt)
347 spin_lock(&xprt->xpt_lock); 347 spin_lock(&xprt->xpt_lock);
348 ipm = xprt->xpt_auth_cache; 348 ipm = xprt->xpt_auth_cache;
349 if (ipm != NULL) { 349 if (ipm != NULL) {
350 if (!cache_valid(&ipm->h)) { 350 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
351 if (cache_is_expired(sn->ip_map_cache, &ipm->h)) {
351 /* 352 /*
352 * The entry has been invalidated since it was 353 * The entry has been invalidated since it was
353 * remembered, e.g. by a second mount from the 354 * remembered, e.g. by a second mount from the
354 * same IP address. 355 * same IP address.
355 */ 356 */
356 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
357 xprt->xpt_auth_cache = NULL; 357 xprt->xpt_auth_cache = NULL;
358 spin_unlock(&xprt->xpt_lock); 358 spin_unlock(&xprt->xpt_lock);
359 cache_put(&ipm->h, sn->ip_map_cache); 359 cache_put(&ipm->h, sn->ip_map_cache);
@@ -493,8 +493,6 @@ static int unix_gid_parse(struct cache_detail *cd,
493 if (rv) 493 if (rv)
494 return -EINVAL; 494 return -EINVAL;
495 uid = make_kuid(&init_user_ns, id); 495 uid = make_kuid(&init_user_ns, id);
496 if (!uid_valid(uid))
497 return -EINVAL;
498 ug.uid = uid; 496 ug.uid = uid;
499 497
500 expiry = get_expiry(&mesg); 498 expiry = get_expiry(&mesg);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 0f679df7d072..305374d4fb98 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -917,7 +917,10 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
917 len = svsk->sk_datalen; 917 len = svsk->sk_datalen;
918 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 918 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
919 for (i = 0; i < npages; i++) { 919 for (i = 0; i < npages; i++) {
920 BUG_ON(svsk->sk_pages[i] == NULL); 920 if (svsk->sk_pages[i] == NULL) {
921 WARN_ON_ONCE(1);
922 continue;
923 }
921 put_page(svsk->sk_pages[i]); 924 put_page(svsk->sk_pages[i]);
922 svsk->sk_pages[i] = NULL; 925 svsk->sk_pages[i] = NULL;
923 } 926 }
@@ -1092,8 +1095,10 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1092 goto err_noclose; 1095 goto err_noclose;
1093 } 1096 }
1094 1097
1095 if (svc_sock_reclen(svsk) < 8) 1098 if (svsk->sk_datalen < 8) {
1099 svsk->sk_datalen = 0;
1096 goto err_delete; /* client is nuts. */ 1100 goto err_delete; /* client is nuts. */
1101 }
1097 1102
1098 rqstp->rq_arg.len = svsk->sk_datalen; 1103 rqstp->rq_arg.len = svsk->sk_datalen;
1099 rqstp->rq_arg.page_base = 0; 1104 rqstp->rq_arg.page_base = 0;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 412de7cfcc80..ddf0602603bd 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2534,7 +2534,6 @@ static struct rpc_xprt_ops bc_tcp_ops = {
2534 .reserve_xprt = xprt_reserve_xprt, 2534 .reserve_xprt = xprt_reserve_xprt,
2535 .release_xprt = xprt_release_xprt, 2535 .release_xprt = xprt_release_xprt,
2536 .alloc_slot = xprt_alloc_slot, 2536 .alloc_slot = xprt_alloc_slot,
2537 .rpcbind = xs_local_rpcbind,
2538 .buf_alloc = bc_malloc, 2537 .buf_alloc = bc_malloc,
2539 .buf_free = bc_free, 2538 .buf_free = bc_free,
2540 .send_request = bc_send_request, 2539 .send_request = bc_send_request,
diff --git a/security/capability.c b/security/capability.c
index d32e16e3c6ae..32b515766df1 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -858,7 +858,7 @@ static int cap_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
858 858
859static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) 859static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
860{ 860{
861 return 0; 861 return -EOPNOTSUPP;
862} 862}
863#ifdef CONFIG_KEYS 863#ifdef CONFIG_KEYS
864static int cap_key_alloc(struct key *key, const struct cred *cred, 864static int cap_key_alloc(struct key *key, const struct cred *cred,