aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/Kconfig16
-rw-r--r--fs/nfsd/nfs4proc.c48
-rw-r--r--fs/nfsd/nfs4recover.c20
-rw-r--r--fs/nfsd/nfs4state.c235
-rw-r--r--fs/nfsd/nfs4xdr.c174
-rw-r--r--fs/nfsd/nfsd.h27
-rw-r--r--fs/nfsd/nfssvc.c13
-rw-r--r--fs/nfsd/state.h1
-rw-r--r--fs/nfsd/vfs.c42
-rw-r--r--fs/nfsd/vfs.h7
-rw-r--r--fs/nfsd/xdr4.h4
11 files changed, 458 insertions, 129 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..419572f33b72 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:
@@ -1251,7 +1293,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
1251 * According to RFC3010, this takes precedence over all other errors. 1293 * According to RFC3010, this takes precedence over all other errors.
1252 */ 1294 */
1253 status = nfserr_minor_vers_mismatch; 1295 status = nfserr_minor_vers_mismatch;
1254 if (args->minorversion > nfsd_supported_minorversion) 1296 if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1255 goto out; 1297 goto out;
1256 1298
1257 status = nfs41_check_op_ordering(args); 1299 status = nfs41_check_op_ordering(args);
@@ -1482,7 +1524,7 @@ static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1482static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1524static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1483{ 1525{
1484 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ 1526 return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1485 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\ 1527 1 + 1 + 2 + /* eir_flags, spr_how, spo_must_enforce & _allow */\
1486 2 + /*eir_server_owner.so_minor_id */\ 1528 2 + /*eir_server_owner.so_minor_id */\
1487 /* eir_server_owner.so_major_id<> */\ 1529 /* eir_server_owner.so_major_id<> */\
1488 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ 1530 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 4e9a21db867a..105a3b080d12 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -240,11 +240,16 @@ struct name_list {
240 struct list_head list; 240 struct list_head list;
241}; 241};
242 242
243struct nfs4_dir_ctx {
244 struct dir_context ctx;
245 struct list_head names;
246};
247
243static int 248static int
244nfsd4_build_namelist(void *arg, const char *name, int namlen, 249nfsd4_build_namelist(void *arg, const char *name, int namlen,
245 loff_t offset, u64 ino, unsigned int d_type) 250 loff_t offset, u64 ino, unsigned int d_type)
246{ 251{
247 struct list_head *names = arg; 252 struct nfs4_dir_ctx *ctx = arg;
248 struct name_list *entry; 253 struct name_list *entry;
249 254
250 if (namlen != HEXDIR_LEN - 1) 255 if (namlen != HEXDIR_LEN - 1)
@@ -254,7 +259,7 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
254 return -ENOMEM; 259 return -ENOMEM;
255 memcpy(entry->name, name, HEXDIR_LEN - 1); 260 memcpy(entry->name, name, HEXDIR_LEN - 1);
256 entry->name[HEXDIR_LEN - 1] = '\0'; 261 entry->name[HEXDIR_LEN - 1] = '\0';
257 list_add(&entry->list, names); 262 list_add(&entry->list, &ctx->names);
258 return 0; 263 return 0;
259} 264}
260 265
@@ -263,7 +268,10 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
263{ 268{
264 const struct cred *original_cred; 269 const struct cred *original_cred;
265 struct dentry *dir = nn->rec_file->f_path.dentry; 270 struct dentry *dir = nn->rec_file->f_path.dentry;
266 LIST_HEAD(names); 271 struct nfs4_dir_ctx ctx = {
272 .ctx.actor = nfsd4_build_namelist,
273 .names = LIST_HEAD_INIT(ctx.names)
274 };
267 int status; 275 int status;
268 276
269 status = nfs4_save_creds(&original_cred); 277 status = nfs4_save_creds(&original_cred);
@@ -276,11 +284,11 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
276 return status; 284 return status;
277 } 285 }
278 286
279 status = vfs_readdir(nn->rec_file, nfsd4_build_namelist, &names); 287 status = iterate_dir(nn->rec_file, &ctx.ctx);
280 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); 288 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
281 while (!list_empty(&names)) { 289 while (!list_empty(&ctx.names)) {
282 struct name_list *entry; 290 struct name_list *entry;
283 entry = list_entry(names.next, struct name_list, list); 291 entry = list_entry(ctx.names.next, struct name_list, list);
284 if (!status) { 292 if (!status) {
285 struct dentry *dentry; 293 struct dentry *dentry;
286 dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1); 294 dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 316ec843dec2..43f42290e5df 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,33 @@ 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 if (!cr->cr_gss_mech)
1268 return false;
1269 service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor);
1270 return service == RPC_GSS_SVC_INTEGRITY ||
1271 service == RPC_GSS_SVC_PRIVACY;
1272}
1273
1274static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp)
1275{
1276 struct svc_cred *cr = &rqstp->rq_cred;
1277
1278 if (!cl->cl_mach_cred)
1279 return true;
1280 if (cl->cl_cred.cr_gss_mech != cr->cr_gss_mech)
1281 return false;
1282 if (!svc_rqst_integrity_protected(rqstp))
1283 return false;
1284 if (!cr->cr_principal)
1285 return false;
1286 return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal);
1287}
1288
1265static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn) 1289static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
1266{ 1290{
1267 static u32 current_clientid = 1; 1291 static u32 current_clientid = 1;
@@ -1639,16 +1663,16 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1639 if (exid->flags & ~EXCHGID4_FLAG_MASK_A) 1663 if (exid->flags & ~EXCHGID4_FLAG_MASK_A)
1640 return nfserr_inval; 1664 return nfserr_inval;
1641 1665
1642 /* Currently only support SP4_NONE */
1643 switch (exid->spa_how) { 1666 switch (exid->spa_how) {
1667 case SP4_MACH_CRED:
1668 if (!svc_rqst_integrity_protected(rqstp))
1669 return nfserr_inval;
1644 case SP4_NONE: 1670 case SP4_NONE:
1645 break; 1671 break;
1646 default: /* checked by xdr code */ 1672 default: /* checked by xdr code */
1647 WARN_ON_ONCE(1); 1673 WARN_ON_ONCE(1);
1648 case SP4_SSV: 1674 case SP4_SSV:
1649 return nfserr_encr_alg_unsupp; 1675 return nfserr_encr_alg_unsupp;
1650 case SP4_MACH_CRED:
1651 return nfserr_serverfault; /* no excuse :-/ */
1652 } 1676 }
1653 1677
1654 /* Cases below refer to rfc 5661 section 18.35.4: */ 1678 /* Cases below refer to rfc 5661 section 18.35.4: */
@@ -1663,6 +1687,10 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1663 status = nfserr_inval; 1687 status = nfserr_inval;
1664 goto out; 1688 goto out;
1665 } 1689 }
1690 if (!mach_creds_match(conf, rqstp)) {
1691 status = nfserr_wrong_cred;
1692 goto out;
1693 }
1666 if (!creds_match) { /* case 9 */ 1694 if (!creds_match) { /* case 9 */
1667 status = nfserr_perm; 1695 status = nfserr_perm;
1668 goto out; 1696 goto out;
@@ -1709,7 +1737,8 @@ out_new:
1709 status = nfserr_jukebox; 1737 status = nfserr_jukebox;
1710 goto out; 1738 goto out;
1711 } 1739 }
1712 new->cl_minorversion = 1; 1740 new->cl_minorversion = cstate->minorversion;
1741 new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED);
1713 1742
1714 gen_clid(new, nn); 1743 gen_clid(new, nn);
1715 add_to_unconfirmed(new); 1744 add_to_unconfirmed(new);
@@ -1839,6 +1868,24 @@ static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
1839 return nfs_ok; 1868 return nfs_ok;
1840} 1869}
1841 1870
1871static __be32 nfsd4_check_cb_sec(struct nfsd4_cb_sec *cbs)
1872{
1873 switch (cbs->flavor) {
1874 case RPC_AUTH_NULL:
1875 case RPC_AUTH_UNIX:
1876 return nfs_ok;
1877 default:
1878 /*
1879 * GSS case: the spec doesn't allow us to return this
1880 * error. But it also doesn't allow us not to support
1881 * GSS.
1882 * I'd rather this fail hard than return some error the
1883 * client might think it can already handle:
1884 */
1885 return nfserr_encr_alg_unsupp;
1886 }
1887}
1888
1842__be32 1889__be32
1843nfsd4_create_session(struct svc_rqst *rqstp, 1890nfsd4_create_session(struct svc_rqst *rqstp,
1844 struct nfsd4_compound_state *cstate, 1891 struct nfsd4_compound_state *cstate,
@@ -1854,6 +1901,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1854 1901
1855 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1902 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1856 return nfserr_inval; 1903 return nfserr_inval;
1904 status = nfsd4_check_cb_sec(&cr_ses->cb_sec);
1905 if (status)
1906 return status;
1857 status = check_forechannel_attrs(&cr_ses->fore_channel, nn); 1907 status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
1858 if (status) 1908 if (status)
1859 return status; 1909 return status;
@@ -1874,6 +1924,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1874 WARN_ON_ONCE(conf && unconf); 1924 WARN_ON_ONCE(conf && unconf);
1875 1925
1876 if (conf) { 1926 if (conf) {
1927 status = nfserr_wrong_cred;
1928 if (!mach_creds_match(conf, rqstp))
1929 goto out_free_conn;
1877 cs_slot = &conf->cl_cs_slot; 1930 cs_slot = &conf->cl_cs_slot;
1878 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1931 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1879 if (status == nfserr_replay_cache) { 1932 if (status == nfserr_replay_cache) {
@@ -1890,6 +1943,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1890 status = nfserr_clid_inuse; 1943 status = nfserr_clid_inuse;
1891 goto out_free_conn; 1944 goto out_free_conn;
1892 } 1945 }
1946 status = nfserr_wrong_cred;
1947 if (!mach_creds_match(unconf, rqstp))
1948 goto out_free_conn;
1893 cs_slot = &unconf->cl_cs_slot; 1949 cs_slot = &unconf->cl_cs_slot;
1894 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1950 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1895 if (status) { 1951 if (status) {
@@ -1957,7 +2013,11 @@ __be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state
1957{ 2013{
1958 struct nfsd4_session *session = cstate->session; 2014 struct nfsd4_session *session = cstate->session;
1959 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 2015 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2016 __be32 status;
1960 2017
2018 status = nfsd4_check_cb_sec(&bc->bc_cb_sec);
2019 if (status)
2020 return status;
1961 spin_lock(&nn->client_lock); 2021 spin_lock(&nn->client_lock);
1962 session->se_cb_prog = bc->bc_cb_program; 2022 session->se_cb_prog = bc->bc_cb_program;
1963 session->se_cb_sec = bc->bc_cb_sec; 2023 session->se_cb_sec = bc->bc_cb_sec;
@@ -1986,6 +2046,9 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
1986 status = nfserr_badsession; 2046 status = nfserr_badsession;
1987 if (!session) 2047 if (!session)
1988 goto out; 2048 goto out;
2049 status = nfserr_wrong_cred;
2050 if (!mach_creds_match(session->se_client, rqstp))
2051 goto out;
1989 status = nfsd4_map_bcts_dir(&bcts->dir); 2052 status = nfsd4_map_bcts_dir(&bcts->dir);
1990 if (status) 2053 if (status)
1991 goto out; 2054 goto out;
@@ -2014,6 +2077,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2014{ 2077{
2015 struct nfsd4_session *ses; 2078 struct nfsd4_session *ses;
2016 __be32 status; 2079 __be32 status;
2080 int ref_held_by_me = 0;
2017 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id); 2081 struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id);
2018 2082
2019 nfs4_lock_state(); 2083 nfs4_lock_state();
@@ -2021,6 +2085,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
2021 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) { 2085 if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
2022 if (!nfsd4_last_compound_op(r)) 2086 if (!nfsd4_last_compound_op(r))
2023 goto out; 2087 goto out;
2088 ref_held_by_me++;
2024 } 2089 }
2025 dump_sessionid(__func__, &sessionid->sessionid); 2090 dump_sessionid(__func__, &sessionid->sessionid);
2026 spin_lock(&nn->client_lock); 2091 spin_lock(&nn->client_lock);
@@ -2028,17 +2093,22 @@ nfsd4_destroy_session(struct svc_rqst *r,
2028 status = nfserr_badsession; 2093 status = nfserr_badsession;
2029 if (!ses) 2094 if (!ses)
2030 goto out_client_lock; 2095 goto out_client_lock;
2031 status = mark_session_dead_locked(ses); 2096 status = nfserr_wrong_cred;
2032 if (status) 2097 if (!mach_creds_match(ses->se_client, r))
2033 goto out_client_lock; 2098 goto out_client_lock;
2099 nfsd4_get_session_locked(ses);
2100 status = mark_session_dead_locked(ses, 1 + ref_held_by_me);
2101 if (status)
2102 goto out_put_session;
2034 unhash_session(ses); 2103 unhash_session(ses);
2035 spin_unlock(&nn->client_lock); 2104 spin_unlock(&nn->client_lock);
2036 2105
2037 nfsd4_probe_callback_sync(ses->se_client); 2106 nfsd4_probe_callback_sync(ses->se_client);
2038 2107
2039 spin_lock(&nn->client_lock); 2108 spin_lock(&nn->client_lock);
2040 free_session(ses);
2041 status = nfs_ok; 2109 status = nfs_ok;
2110out_put_session:
2111 nfsd4_put_session(ses);
2042out_client_lock: 2112out_client_lock:
2043 spin_unlock(&nn->client_lock); 2113 spin_unlock(&nn->client_lock);
2044out: 2114out:
@@ -2058,26 +2128,31 @@ static struct nfsd4_conn *__nfsd4_find_conn(struct svc_xprt *xpt, struct nfsd4_s
2058 return NULL; 2128 return NULL;
2059} 2129}
2060 2130
2061static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses) 2131static __be32 nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_session *ses)
2062{ 2132{
2063 struct nfs4_client *clp = ses->se_client; 2133 struct nfs4_client *clp = ses->se_client;
2064 struct nfsd4_conn *c; 2134 struct nfsd4_conn *c;
2135 __be32 status = nfs_ok;
2065 int ret; 2136 int ret;
2066 2137
2067 spin_lock(&clp->cl_lock); 2138 spin_lock(&clp->cl_lock);
2068 c = __nfsd4_find_conn(new->cn_xprt, ses); 2139 c = __nfsd4_find_conn(new->cn_xprt, ses);
2069 if (c) { 2140 if (c)
2070 spin_unlock(&clp->cl_lock); 2141 goto out_free;
2071 free_conn(new); 2142 status = nfserr_conn_not_bound_to_session;
2072 return; 2143 if (clp->cl_mach_cred)
2073 } 2144 goto out_free;
2074 __nfsd4_hash_conn(new, ses); 2145 __nfsd4_hash_conn(new, ses);
2075 spin_unlock(&clp->cl_lock); 2146 spin_unlock(&clp->cl_lock);
2076 ret = nfsd4_register_conn(new); 2147 ret = nfsd4_register_conn(new);
2077 if (ret) 2148 if (ret)
2078 /* oops; xprt is already down: */ 2149 /* oops; xprt is already down: */
2079 nfsd4_conn_lost(&new->cn_xpt_user); 2150 nfsd4_conn_lost(&new->cn_xpt_user);
2080 return; 2151 return nfs_ok;
2152out_free:
2153 spin_unlock(&clp->cl_lock);
2154 free_conn(new);
2155 return status;
2081} 2156}
2082 2157
2083static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) 2158static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session)
@@ -2169,8 +2244,10 @@ nfsd4_sequence(struct svc_rqst *rqstp,
2169 if (status) 2244 if (status)
2170 goto out_put_session; 2245 goto out_put_session;
2171 2246
2172 nfsd4_sequence_check_conn(conn, session); 2247 status = nfsd4_sequence_check_conn(conn, session);
2173 conn = NULL; 2248 conn = NULL;
2249 if (status)
2250 goto out_put_session;
2174 2251
2175 /* Success! bump slot seqid */ 2252 /* Success! bump slot seqid */
2176 slot->sl_seqid = seq->seqid; 2253 slot->sl_seqid = seq->seqid;
@@ -2232,7 +2309,10 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2232 status = nfserr_stale_clientid; 2309 status = nfserr_stale_clientid;
2233 goto out; 2310 goto out;
2234 } 2311 }
2235 2312 if (!mach_creds_match(clp, rqstp)) {
2313 status = nfserr_wrong_cred;
2314 goto out;
2315 }
2236 expire_client(clp); 2316 expire_client(clp);
2237out: 2317out:
2238 nfs4_unlock_state(); 2318 nfs4_unlock_state();
@@ -2645,13 +2725,13 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
2645 2725
2646 list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru); 2726 list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
2647 2727
2648 /* only place dl_time is set. protected by lock_flocks*/ 2728 /* Only place dl_time is set; protected by i_lock: */
2649 dp->dl_time = get_seconds(); 2729 dp->dl_time = get_seconds();
2650 2730
2651 nfsd4_cb_recall(dp); 2731 nfsd4_cb_recall(dp);
2652} 2732}
2653 2733
2654/* Called from break_lease() with lock_flocks() held. */ 2734/* Called from break_lease() with i_lock held. */
2655static void nfsd_break_deleg_cb(struct file_lock *fl) 2735static void nfsd_break_deleg_cb(struct file_lock *fl)
2656{ 2736{
2657 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; 2737 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
@@ -2940,13 +3020,13 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int f
2940 return fl; 3020 return fl;
2941} 3021}
2942 3022
2943static int nfs4_setlease(struct nfs4_delegation *dp, int flag) 3023static int nfs4_setlease(struct nfs4_delegation *dp)
2944{ 3024{
2945 struct nfs4_file *fp = dp->dl_file; 3025 struct nfs4_file *fp = dp->dl_file;
2946 struct file_lock *fl; 3026 struct file_lock *fl;
2947 int status; 3027 int status;
2948 3028
2949 fl = nfs4_alloc_init_lease(dp, flag); 3029 fl = nfs4_alloc_init_lease(dp, NFS4_OPEN_DELEGATE_READ);
2950 if (!fl) 3030 if (!fl)
2951 return -ENOMEM; 3031 return -ENOMEM;
2952 fl->fl_file = find_readable_file(fp); 3032 fl->fl_file = find_readable_file(fp);
@@ -2964,12 +3044,12 @@ static int nfs4_setlease(struct nfs4_delegation *dp, int flag)
2964 return 0; 3044 return 0;
2965} 3045}
2966 3046
2967static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) 3047static int nfs4_set_delegation(struct nfs4_delegation *dp)
2968{ 3048{
2969 struct nfs4_file *fp = dp->dl_file; 3049 struct nfs4_file *fp = dp->dl_file;
2970 3050
2971 if (!fp->fi_lease) 3051 if (!fp->fi_lease)
2972 return nfs4_setlease(dp, flag); 3052 return nfs4_setlease(dp);
2973 spin_lock(&recall_lock); 3053 spin_lock(&recall_lock);
2974 if (fp->fi_had_conflict) { 3054 if (fp->fi_had_conflict) {
2975 spin_unlock(&recall_lock); 3055 spin_unlock(&recall_lock);
@@ -3005,6 +3085,9 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
3005 3085
3006/* 3086/*
3007 * Attempt to hand out a delegation. 3087 * Attempt to hand out a delegation.
3088 *
3089 * Note we don't support write delegations, and won't until the vfs has
3090 * proper support for them.
3008 */ 3091 */
3009static void 3092static void
3010nfs4_open_delegation(struct net *net, struct svc_fh *fh, 3093nfs4_open_delegation(struct net *net, struct svc_fh *fh,
@@ -3013,39 +3096,45 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3013 struct nfs4_delegation *dp; 3096 struct nfs4_delegation *dp;
3014 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner); 3097 struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
3015 int cb_up; 3098 int cb_up;
3016 int status = 0, flag = 0; 3099 int status = 0;
3017 3100
3018 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client); 3101 cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
3019 flag = NFS4_OPEN_DELEGATE_NONE;
3020 open->op_recall = 0; 3102 open->op_recall = 0;
3021 switch (open->op_claim_type) { 3103 switch (open->op_claim_type) {
3022 case NFS4_OPEN_CLAIM_PREVIOUS: 3104 case NFS4_OPEN_CLAIM_PREVIOUS:
3023 if (!cb_up) 3105 if (!cb_up)
3024 open->op_recall = 1; 3106 open->op_recall = 1;
3025 flag = open->op_delegate_type; 3107 if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ)
3026 if (flag == NFS4_OPEN_DELEGATE_NONE) 3108 goto out_no_deleg;
3027 goto out;
3028 break; 3109 break;
3029 case NFS4_OPEN_CLAIM_NULL: 3110 case NFS4_OPEN_CLAIM_NULL:
3030 /* Let's not give out any delegations till everyone's 3111 /*
3031 * had the chance to reclaim theirs.... */ 3112 * Let's not give out any delegations till everyone's
3113 * had the chance to reclaim theirs....
3114 */
3032 if (locks_in_grace(net)) 3115 if (locks_in_grace(net))
3033 goto out; 3116 goto out_no_deleg;
3034 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) 3117 if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
3035 goto out; 3118 goto out_no_deleg;
3119 /*
3120 * Also, if the file was opened for write or
3121 * create, there's a good chance the client's
3122 * about to write to it, resulting in an
3123 * immediate recall (since we don't support
3124 * write delegations):
3125 */
3036 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 3126 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
3037 flag = NFS4_OPEN_DELEGATE_WRITE; 3127 goto out_no_deleg;
3038 else 3128 if (open->op_create == NFS4_OPEN_CREATE)
3039 flag = NFS4_OPEN_DELEGATE_READ; 3129 goto out_no_deleg;
3040 break; 3130 break;
3041 default: 3131 default:
3042 goto out; 3132 goto out_no_deleg;
3043 } 3133 }
3044 3134 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) 3135 if (dp == NULL)
3047 goto out_no_deleg; 3136 goto out_no_deleg;
3048 status = nfs4_set_delegation(dp, flag); 3137 status = nfs4_set_delegation(dp);
3049 if (status) 3138 if (status)
3050 goto out_free; 3139 goto out_free;
3051 3140
@@ -3053,24 +3142,23 @@ nfs4_open_delegation(struct net *net, struct svc_fh *fh,
3053 3142
3054 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", 3143 dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
3055 STATEID_VAL(&dp->dl_stid.sc_stateid)); 3144 STATEID_VAL(&dp->dl_stid.sc_stateid));
3056out: 3145 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; 3146 return;
3068out_free: 3147out_free:
3069 unhash_stid(&dp->dl_stid); 3148 unhash_stid(&dp->dl_stid);
3070 nfs4_put_delegation(dp); 3149 nfs4_put_delegation(dp);
3071out_no_deleg: 3150out_no_deleg:
3072 flag = NFS4_OPEN_DELEGATE_NONE; 3151 open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
3073 goto out; 3152 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
3153 open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) {
3154 dprintk("NFSD: WARNING: refusing delegation reclaim\n");
3155 open->op_recall = 1;
3156 }
3157
3158 /* 4.1 client asking for a delegation? */
3159 if (open->op_deleg_want)
3160 nfsd4_open_deleg_none_ext(open, status);
3161 return;
3074} 3162}
3075 3163
3076static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, 3164static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
@@ -3427,7 +3515,7 @@ grace_disallows_io(struct net *net, struct inode *inode)
3427/* Returns true iff a is later than b: */ 3515/* Returns true iff a is later than b: */
3428static bool stateid_generation_after(stateid_t *a, stateid_t *b) 3516static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3429{ 3517{
3430 return (s32)a->si_generation - (s32)b->si_generation > 0; 3518 return (s32)(a->si_generation - b->si_generation) > 0;
3431} 3519}
3432 3520
3433static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3521static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
@@ -4435,7 +4523,6 @@ __be32
4435nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, 4523nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4436 struct nfsd4_locku *locku) 4524 struct nfsd4_locku *locku)
4437{ 4525{
4438 struct nfs4_lockowner *lo;
4439 struct nfs4_ol_stateid *stp; 4526 struct nfs4_ol_stateid *stp;
4440 struct file *filp = NULL; 4527 struct file *filp = NULL;
4441 struct file_lock *file_lock = NULL; 4528 struct file_lock *file_lock = NULL;
@@ -4468,10 +4555,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4468 status = nfserr_jukebox; 4555 status = nfserr_jukebox;
4469 goto out; 4556 goto out;
4470 } 4557 }
4471 lo = lockowner(stp->st_stateowner);
4472 locks_init_lock(file_lock); 4558 locks_init_lock(file_lock);
4473 file_lock->fl_type = F_UNLCK; 4559 file_lock->fl_type = F_UNLCK;
4474 file_lock->fl_owner = (fl_owner_t)lo; 4560 file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
4475 file_lock->fl_pid = current->tgid; 4561 file_lock->fl_pid = current->tgid;
4476 file_lock->fl_file = filp; 4562 file_lock->fl_file = filp;
4477 file_lock->fl_flags = FL_POSIX; 4563 file_lock->fl_flags = FL_POSIX;
@@ -4490,11 +4576,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4490 update_stateid(&stp->st_stid.sc_stateid); 4576 update_stateid(&stp->st_stid.sc_stateid);
4491 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 4577 memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
4492 4578
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: 4579out:
4499 nfsd4_bump_seqid(cstate, status); 4580 nfsd4_bump_seqid(cstate, status);
4500 if (!cstate->replay_owner) 4581 if (!cstate->replay_owner)
@@ -4520,7 +4601,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4520 struct inode *inode = filp->fi_inode; 4601 struct inode *inode = filp->fi_inode;
4521 int status = 0; 4602 int status = 0;
4522 4603
4523 lock_flocks(); 4604 spin_lock(&inode->i_lock);
4524 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { 4605 for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) {
4525 if ((*flpp)->fl_owner == (fl_owner_t)lowner) { 4606 if ((*flpp)->fl_owner == (fl_owner_t)lowner) {
4526 status = 1; 4607 status = 1;
@@ -4528,7 +4609,7 @@ check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner)
4528 } 4609 }
4529 } 4610 }
4530out: 4611out:
4531 unlock_flocks(); 4612 spin_unlock(&inode->i_lock);
4532 return status; 4613 return status;
4533} 4614}
4534 4615
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6cd86e0fe450..c2a4701d7286 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)
@@ -3249,7 +3360,8 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3249 8 /* eir_clientid */ + 3360 8 /* eir_clientid */ +
3250 4 /* eir_sequenceid */ + 3361 4 /* eir_sequenceid */ +
3251 4 /* eir_flags */ + 3362 4 /* eir_flags */ +
3252 4 /* spr_how (SP4_NONE) */ + 3363 4 /* spr_how */ +
3364 8 /* spo_must_enforce, spo_must_allow */ +
3253 8 /* so_minor_id */ + 3365 8 /* so_minor_id */ +
3254 4 /* so_major_id.len */ + 3366 4 /* so_major_id.len */ +
3255 (XDR_QUADLEN(major_id_sz) * 4) + 3367 (XDR_QUADLEN(major_id_sz) * 4) +
@@ -3261,9 +3373,21 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3261 WRITE32(exid->seqid); 3373 WRITE32(exid->seqid);
3262 WRITE32(exid->flags); 3374 WRITE32(exid->flags);
3263 3375
3264 /* state_protect4_r. Currently only support SP4_NONE */
3265 BUG_ON(exid->spa_how != SP4_NONE);
3266 WRITE32(exid->spa_how); 3376 WRITE32(exid->spa_how);
3377 switch (exid->spa_how) {
3378 case SP4_NONE:
3379 break;
3380 case SP4_MACH_CRED:
3381 /* spo_must_enforce bitmap: */
3382 WRITE32(2);
3383 WRITE32(nfs4_minimal_spo_must_enforce[0]);
3384 WRITE32(nfs4_minimal_spo_must_enforce[1]);
3385 /* empty spo_must_allow bitmap: */
3386 WRITE32(0);
3387 break;
3388 default:
3389 WARN_ON_ONCE(1);
3390 }
3267 3391
3268 /* The server_owner struct */ 3392 /* The server_owner struct */
3269 WRITE64(minor_id); /* Minor id */ 3393 WRITE64(minor_id); /* Minor id */
@@ -3635,13 +3759,17 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
3635 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base; 3759 iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3636 BUG_ON(iov->iov_len > PAGE_SIZE); 3760 BUG_ON(iov->iov_len > PAGE_SIZE);
3637 if (nfsd4_has_session(cs)) { 3761 if (nfsd4_has_session(cs)) {
3762 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
3763 struct nfs4_client *clp = cs->session->se_client;
3638 if (cs->status != nfserr_replay_cache) { 3764 if (cs->status != nfserr_replay_cache) {
3639 nfsd4_store_cache_entry(resp); 3765 nfsd4_store_cache_entry(resp);
3640 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE; 3766 cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
3641 } 3767 }
3642 /* Renew the clientid on success and on replay */ 3768 /* Renew the clientid on success and on replay */
3643 put_client_renew(cs->session->se_client); 3769 spin_lock(&nn->client_lock);
3644 nfsd4_put_session(cs->session); 3770 nfsd4_put_session(cs->session);
3771 spin_unlock(&nn->client_lock);
3772 put_client_renew(clp);
3645 } 3773 }
3646 return 1; 3774 return 1;
3647} 3775}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 07a473fd49bc..30f34ab02137 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 */
@@ -53,7 +53,6 @@ struct readdir_cd {
53extern struct svc_program nfsd_program; 53extern struct svc_program nfsd_program;
54extern struct svc_version nfsd_version2, nfsd_version3, 54extern struct svc_version nfsd_version2, nfsd_version3,
55 nfsd_version4; 55 nfsd_version4;
56extern u32 nfsd_supported_minorversion;
57extern struct mutex nfsd_mutex; 56extern struct mutex nfsd_mutex;
58extern spinlock_t nfsd_drc_lock; 57extern spinlock_t nfsd_drc_lock;
59extern unsigned long nfsd_drc_max_mem; 58extern unsigned long nfsd_drc_max_mem;
@@ -243,6 +242,12 @@ void nfsd_lockd_shutdown(void);
243#define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) 242#define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG)
244#define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) 243#define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT)
245#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) 244#define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED)
245#define nfserr_partner_notsupp cpu_to_be32(NFS4ERR_PARTNER_NOTSUPP)
246#define nfserr_partner_no_auth cpu_to_be32(NFS4ERR_PARTNER_NO_AUTH)
247#define nfserr_metadata_notsupp cpu_to_be32(NFS4ERR_METADATA_NOTSUPP)
248#define nfserr_offload_denied cpu_to_be32(NFS4ERR_OFFLOAD_DENIED)
249#define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS)
250#define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL)
246 251
247/* error codes for internal use */ 252/* error codes for internal use */
248/* if a request fails due to kmalloc failure, it gets dropped. 253/* if a request fails due to kmalloc failure, it gets dropped.
@@ -322,6 +327,13 @@ void nfsd_lockd_shutdown(void);
322#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ 327#define NFSD4_1_SUPPORTED_ATTRS_WORD2 \
323 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) 328 (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
324 329
330#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
331#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
332 (NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL)
333#else
334#define NFSD4_2_SUPPORTED_ATTRS_WORD2 0
335#endif
336
325static inline u32 nfsd_suppattrs0(u32 minorversion) 337static inline u32 nfsd_suppattrs0(u32 minorversion)
326{ 338{
327 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 339 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
@@ -336,8 +348,11 @@ static inline u32 nfsd_suppattrs1(u32 minorversion)
336 348
337static inline u32 nfsd_suppattrs2(u32 minorversion) 349static inline u32 nfsd_suppattrs2(u32 minorversion)
338{ 350{
339 return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2 351 switch (minorversion) {
340 : NFSD4_SUPPORTED_ATTRS_WORD2; 352 default: return NFSD4_2_SUPPORTED_ATTRS_WORD2;
353 case 1: return NFSD4_1_SUPPORTED_ATTRS_WORD2;
354 case 0: return NFSD4_SUPPORTED_ATTRS_WORD2;
355 }
341} 356}
342 357
343/* These will return ERR_INVAL if specified in GETATTR or READDIR. */ 358/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
@@ -350,7 +365,11 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
350#define NFSD_WRITEABLE_ATTRS_WORD1 \ 365#define NFSD_WRITEABLE_ATTRS_WORD1 \
351 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ 366 (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
352 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) 367 | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
368#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
369#define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL
370#else
353#define NFSD_WRITEABLE_ATTRS_WORD2 0 371#define NFSD_WRITEABLE_ATTRS_WORD2 0
372#endif
354 373
355#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ 374#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
356 NFSD_WRITEABLE_ATTRS_WORD0 375 NFSD_WRITEABLE_ATTRS_WORD0
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 262df5ccbf59..760c85a6f534 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -116,7 +116,10 @@ struct svc_program nfsd_program = {
116 116
117}; 117};
118 118
119u32 nfsd_supported_minorversion; 119static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
120 [0] = 1,
121 [1] = 1,
122};
120 123
121int nfsd_vers(int vers, enum vers_op change) 124int nfsd_vers(int vers, enum vers_op change)
122{ 125{
@@ -151,15 +154,13 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
151 return -1; 154 return -1;
152 switch(change) { 155 switch(change) {
153 case NFSD_SET: 156 case NFSD_SET:
154 nfsd_supported_minorversion = minorversion; 157 nfsd_supported_minorversions[minorversion] = true;
155 break; 158 break;
156 case NFSD_CLEAR: 159 case NFSD_CLEAR:
157 if (minorversion == 0) 160 nfsd_supported_minorversions[minorversion] = false;
158 return -1;
159 nfsd_supported_minorversion = minorversion - 1;
160 break; 161 break;
161 case NFSD_TEST: 162 case NFSD_TEST:
162 return minorversion <= nfsd_supported_minorversion; 163 return nfsd_supported_minorversions[minorversion];
163 case NFSD_AVAIL: 164 case NFSD_AVAIL:
164 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION; 165 return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
165 } 166 }
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 84ce601d8063..c827acb0e943 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
@@ -802,9 +830,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
802 flags = O_WRONLY|O_LARGEFILE; 830 flags = O_WRONLY|O_LARGEFILE;
803 } 831 }
804 *filp = dentry_open(&path, flags, current_cred()); 832 *filp = dentry_open(&path, flags, current_cred());
805 if (IS_ERR(*filp)) 833 if (IS_ERR(*filp)) {
806 host_err = PTR_ERR(*filp); 834 host_err = PTR_ERR(*filp);
807 else { 835 *filp = NULL;
836 } else {
808 host_err = ima_file_check(*filp, may_flags); 837 host_err = ima_file_check(*filp, may_flags);
809 838
810 if (may_flags & NFSD_MAY_64BIT_COOKIE) 839 if (may_flags & NFSD_MAY_64BIT_COOKIE)
@@ -1912,6 +1941,7 @@ struct buffered_dirent {
1912}; 1941};
1913 1942
1914struct readdir_data { 1943struct readdir_data {
1944 struct dir_context ctx;
1915 char *dirent; 1945 char *dirent;
1916 size_t used; 1946 size_t used;
1917 int full; 1947 int full;
@@ -1943,13 +1973,15 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
1943static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func, 1973static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func,
1944 struct readdir_cd *cdp, loff_t *offsetp) 1974 struct readdir_cd *cdp, loff_t *offsetp)
1945{ 1975{
1946 struct readdir_data buf;
1947 struct buffered_dirent *de; 1976 struct buffered_dirent *de;
1948 int host_err; 1977 int host_err;
1949 int size; 1978 int size;
1950 loff_t offset; 1979 loff_t offset;
1980 struct readdir_data buf = {
1981 .ctx.actor = nfsd_buffered_filldir,
1982 .dirent = (void *)__get_free_page(GFP_KERNEL)
1983 };
1951 1984
1952 buf.dirent = (void *)__get_free_page(GFP_KERNEL);
1953 if (!buf.dirent) 1985 if (!buf.dirent)
1954 return nfserrno(-ENOMEM); 1986 return nfserrno(-ENOMEM);
1955 1987
@@ -1963,7 +1995,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func,
1963 buf.used = 0; 1995 buf.used = 0;
1964 buf.full = 0; 1996 buf.full = 0;
1965 1997
1966 host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf); 1998 host_err = iterate_dir(file, &buf.ctx);
1967 if (buf.full) 1999 if (buf.full)
1968 host_err = 0; 2000 host_err = 0;
1969 2001
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 {