linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Initial SP4_MACH_CRED implementation
@ 2013-08-13 20:37 Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 1/7] nfs4.1: Minimal " Weston Andros Adamson
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

This is version 2 of this patchset including some cleanup, refactoring and
fixes a few build issues with different configs.

I also added a few patches:
 - WRITE and/or COMMIT support - tested on a hacked nfsd
 - map NFS4ERR_WRONG_CRED (an common SP4 error) to EPERM

I meant to include a patch that only uses the machine cred (for 'allow' ops)
when the user cred has expired, but after talking with Andy, I decided to wait
for his cred expiration patchset to be merged as we'd be touching the same
places and possibly duplicating effort.

Weston Andros Adamson (7):
  nfs4.1: Minimal SP4_MACH_CRED implementation
  nfs4.1: Add state protection handler
  nfs4.1: Add SP4_MACH_CRED cleanup support
  nfs4.1: Add SP4_MACH_CRED secinfo support
  nfs4.1: Add SP4_MACH_CRED stateid support
  nfs4.1: Add SP4_MACH_CRED write and commit support
  nfs4: Map NFS4ERR_WRONG_CRED to EPERM

 fs/nfs/nfs4_fs.h          |  67 ++++++++++++++++
 fs/nfs/nfs4proc.c         | 191 ++++++++++++++++++++++++++++++++++++++++++++--
 fs/nfs/nfs4xdr.c          |  72 ++++++++++++++---
 fs/nfs/write.c            |   6 ++
 include/linux/nfs_fs_sb.h |   9 +++
 include/linux/nfs_xdr.h   |  19 +++++
 6 files changed, 346 insertions(+), 18 deletions(-)

-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] nfs4.1: Minimal SP4_MACH_CRED implementation
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 2/7] nfs4.1: Add state protection handler Weston Andros Adamson
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

This is a minimal client side implementation of SP4_MACH_CRED.  It will
attempt to negotiate SP4_MACH_CRED iff the EXCHANGE_ID is using
krb5i or krb5p auth.  SP4_MACH_CRED will be used if the server supports the
minimal operations:

 BIND_CONN_TO_SESSION
 EXCHANGE_ID
 CREATE_SESSION
 DESTROY_SESSION
 DESTROY_CLIENTID

This patch only includes the EXCHANGE_ID negotiation code because
the client will already use the machine cred for these operations.

If the server doesn't support SP4_MACH_CRED or doesn't support the minimal
operations, the exchange id will be resent with SP4_NONE.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4proc.c         | 133 +++++++++++++++++++++++++++++++++++++++++++---
 fs/nfs/nfs4xdr.c          |  72 +++++++++++++++++++++----
 include/linux/nfs_fs_sb.h |   4 ++
 include/linux/nfs_xdr.h   |  19 +++++++
 4 files changed, 211 insertions(+), 17 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f672c34..7acf20e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5918,16 +5918,87 @@ out:
 }
 
 /*
- * nfs4_proc_exchange_id()
+ * Minimum set of SP4_MACH_CRED operations from RFC 5661
+ */
+static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
+	.how = SP4_MACH_CRED,
+	.enforce.u.words = {
+		[1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
+		      1 << (OP_EXCHANGE_ID - 32) |
+		      1 << (OP_CREATE_SESSION - 32) |
+		      1 << (OP_DESTROY_SESSION - 32) |
+		      1 << (OP_DESTROY_CLIENTID - 32)
+	}
+};
+
+/*
+ * Select the state protection mode for client `clp' given the server results
+ * from exchange_id in `sp'.
  *
- * Returns zero, a negative errno, or a negative NFS4ERR status code.
+ * Returns 0 on success, negative errno otherwise.
+ */
+static int nfs4_sp4_select_mode(struct nfs_client *clp,
+				 struct nfs41_state_protection *sp)
+{
+	static const u32 supported_enforce[NFS4_OP_MAP_NUM_WORDS] = {
+		[1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
+		      1 << (OP_EXCHANGE_ID - 32) |
+		      1 << (OP_CREATE_SESSION - 32) |
+		      1 << (OP_DESTROY_SESSION - 32) |
+		      1 << (OP_DESTROY_CLIENTID - 32)
+	};
+	unsigned int i;
+
+	if (sp->how == SP4_MACH_CRED) {
+		/* Print state protect result */
+		dfprintk(MOUNT, "Server SP4_MACH_CRED support:\n");
+		for (i = 0; i <= LAST_NFS4_OP; i++) {
+			if (test_bit(i, sp->enforce.u.longs))
+				dfprintk(MOUNT, "  enforce op %d\n", i);
+			if (test_bit(i, sp->allow.u.longs))
+				dfprintk(MOUNT, "  allow op %d\n", i);
+		}
+
+		/* make sure nothing is on enforce list that isn't supported */
+		for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) {
+			if (sp->enforce.u.words[i] & ~supported_enforce[i]) {
+				dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
+				return -EINVAL;
+			}
+		}
+
+		/*
+		 * Minimal mode - state operations are allowed to use machine
+		 * credential.  Note this already happens by default, so the
+		 * client doesn't have to do anything more than the negotiation.
+		 *
+		 * NOTE: we don't care if EXCHANGE_ID is in the list -
+		 *       we're already using the machine cred for exchange_id
+		 *       and will never use a different cred.
+		 */
+		if (test_bit(OP_BIND_CONN_TO_SESSION, sp->enforce.u.longs) &&
+		    test_bit(OP_CREATE_SESSION, sp->enforce.u.longs) &&
+		    test_bit(OP_DESTROY_SESSION, sp->enforce.u.longs) &&
+		    test_bit(OP_DESTROY_CLIENTID, sp->enforce.u.longs)) {
+			dfprintk(MOUNT, "sp4_mach_cred:\n");
+			dfprintk(MOUNT, "  minimal mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_MINIMAL, &clp->cl_sp4_flags);
+		} else {
+			dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * _nfs4_proc_exchange_id()
  *
- * Since the clientid has expired, all compounds using sessions
- * associated with the stale clientid will be returning
- * NFS4ERR_BADSESSION in the sequence operation, and will therefore
- * be in some phase of session reset.
+ * Wrapper for EXCHANGE_ID operation.
  */
-int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
+	u32 sp4_how)
 {
 	nfs4_verifier verifier;
 	struct nfs41_exchange_id_args args = {
@@ -5974,10 +6045,29 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 		goto out_server_scope;
 	}
 
+	switch (sp4_how) {
+	case SP4_NONE:
+		args.state_protect.how = SP4_NONE;
+		break;
+
+	case SP4_MACH_CRED:
+		args.state_protect = nfs4_sp4_mach_cred_request;
+		break;
+
+	default:
+		/* unsupported! */
+		WARN_ON_ONCE(1);
+		status = -EINVAL;
+		goto out_server_scope;
+	}
+
 	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 	if (status == 0)
 		status = nfs4_check_cl_exchange_flags(res.flags);
 
+	if (status == 0)
+		status = nfs4_sp4_select_mode(clp, &res.state_protect);
+
 	if (status == 0) {
 		clp->cl_clientid = res.clientid;
 		clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
@@ -6024,6 +6114,35 @@ out:
 	return status;
 }
 
+/*
+ * nfs4_proc_exchange_id()
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status code.
+ *
+ * Since the clientid has expired, all compounds using sessions
+ * associated with the stale clientid will be returning
+ * NFS4ERR_BADSESSION in the sequence operation, and will therefore
+ * be in some phase of session reset.
+ *
+ * Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
+ */
+int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
+{
+	rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
+	int status;
+
+	/* try SP4_MACH_CRED if krb5i/p	*/
+	if (authflavor == RPC_AUTH_GSS_KRB5I ||
+	    authflavor == RPC_AUTH_GSS_KRB5P) {
+		status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
+		if (!status)
+			return 0;
+	}
+
+	/* try SP4_NONE */
+	return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
+}
+
 static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 		struct rpc_cred *cred)
 {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1a4a3bd..9684354 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -294,7 +294,9 @@ static int nfs4_stat_to_errno(int);
 				XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
 				1 /* flags */ + \
 				1 /* spa_how */ + \
-				0 /* SP4_NONE (for now) */ + \
+				/* max is SP4_MACH_CRED (for now) */ + \
+				1 + NFS4_OP_MAP_NUM_WORDS + \
+				1 + NFS4_OP_MAP_NUM_WORDS + \
 				1 /* implementation id array of size 1 */ + \
 				1 /* nii_domain */ + \
 				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
@@ -306,7 +308,9 @@ static int nfs4_stat_to_errno(int);
 				1 /* eir_sequenceid */ + \
 				1 /* eir_flags */ + \
 				1 /* spr_how */ + \
-				0 /* SP4_NONE (for now) */ + \
+				  /* max is SP4_MACH_CRED (for now) */ + \
+				1 + NFS4_OP_MAP_NUM_WORDS + \
+				1 + NFS4_OP_MAP_NUM_WORDS + \
 				2 /* eir_server_owner.so_minor_id */ + \
 				/* eir_server_owner.so_major_id<> */ \
 				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
@@ -1726,6 +1730,14 @@ static void encode_bind_conn_to_session(struct xdr_stream *xdr,
 	*p = 0;	/* use_conn_in_rdma_mode = False */
 }
 
+static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
+{
+	unsigned int i;
+	encode_uint32(xdr, NFS4_OP_MAP_NUM_WORDS);
+	for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++)
+		encode_uint32(xdr, op_map->u.words[i]);
+}
+
 static void encode_exchange_id(struct xdr_stream *xdr,
 			       struct nfs41_exchange_id_args *args,
 			       struct compound_hdr *hdr)
@@ -1739,9 +1751,20 @@ static void encode_exchange_id(struct xdr_stream *xdr,
 
 	encode_string(xdr, args->id_len, args->id);
 
-	p = reserve_space(xdr, 12);
-	*p++ = cpu_to_be32(args->flags);
-	*p++ = cpu_to_be32(0);	/* zero length state_protect4_a */
+	encode_uint32(xdr, args->flags);
+	encode_uint32(xdr, args->state_protect.how);
+
+	switch (args->state_protect.how) {
+	case SP4_NONE:
+		break;
+	case SP4_MACH_CRED:
+		encode_op_map(xdr, &args->state_protect.enforce);
+		encode_op_map(xdr, &args->state_protect.allow);
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		break;
+	}
 
 	if (send_implementation_id &&
 	    sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
@@ -1752,7 +1775,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
 			       utsname()->version, utsname()->machine);
 
 	if (len > 0) {
-		*p = cpu_to_be32(1);	/* implementation id array length=1 */
+		encode_uint32(xdr, 1);	/* implementation id array length=1 */
 
 		encode_string(xdr,
 			sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
@@ -1763,7 +1786,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
 		p = xdr_encode_hyper(p, 0);
 		*p = cpu_to_be32(0);
 	} else
-		*p = cpu_to_be32(0);	/* implementation id array length=0 */
+		encode_uint32(xdr, 0);	/* implementation id array length=0 */
 }
 
 static void encode_create_session(struct xdr_stream *xdr,
@@ -5375,6 +5398,23 @@ static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_re
 	return decode_secinfo_common(xdr, res);
 }
 
+static int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
+{
+	__be32 *p;
+	uint32_t bitmap_words;
+	unsigned int i;
+
+	p = xdr_inline_decode(xdr, 4);
+	bitmap_words = be32_to_cpup(p++);
+	if (bitmap_words > NFS4_OP_MAP_NUM_WORDS)
+		return -EIO;
+	p = xdr_inline_decode(xdr, 4 * bitmap_words);
+	for (i = 0; i < bitmap_words; i++)
+		op_map->u.words[i] = be32_to_cpup(p++);
+
+	return 0;
+}
+
 static int decode_exchange_id(struct xdr_stream *xdr,
 			      struct nfs41_exchange_id_res *res)
 {
@@ -5398,10 +5438,22 @@ static int decode_exchange_id(struct xdr_stream *xdr,
 	res->seqid = be32_to_cpup(p++);
 	res->flags = be32_to_cpup(p++);
 
-	/* We ask for SP4_NONE */
-	dummy = be32_to_cpup(p);
-	if (dummy != SP4_NONE)
+	res->state_protect.how = be32_to_cpup(p);
+	switch (res->state_protect.how) {
+	case SP4_NONE:
+		break;
+	case SP4_MACH_CRED:
+		status = decode_op_map(xdr, &res->state_protect.enforce);
+		if (status)
+			return status;
+		status = decode_op_map(xdr, &res->state_protect.allow);
+		if (status)
+			return status;
+		break;
+	default:
+		WARN_ON_ONCE(1);
 		return -EIO;
+	}
 
 	/* server_owner4.so_minor_id */
 	p = xdr_inline_decode(xdr, 8);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d221243..a0af429 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -87,6 +87,10 @@ struct nfs_client {
 	struct nfs41_server_owner *cl_serverowner;
 	struct nfs41_server_scope *cl_serverscope;
 	struct nfs41_impl_id	*cl_implid;
+	/* nfs 4.1+ state protection modes: */
+	unsigned long		cl_sp4_flags;
+#define NFS_SP4_MACH_CRED_MINIMAL  1	/* Minimal sp4_mach_cred - state ops
+					 * must use machine cred */
 #endif /* CONFIG_NFS_V4 */
 
 #ifdef CONFIG_NFS_FSCACHE
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index ddc3e32..b32f9d0 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1107,6 +1107,23 @@ struct pnfs_ds_commit_info {
 	struct pnfs_commit_bucket *buckets;
 };
 
+#define NFS4_OP_MAP_NUM_LONGS \
+	DIV_ROUND_UP(LAST_NFS4_OP, 8 * sizeof(unsigned long))
+#define NFS4_OP_MAP_NUM_WORDS \
+	(NFS4_OP_MAP_NUM_LONGS * sizeof(unsigned long) / sizeof(u32))
+struct nfs4_op_map {
+	union {
+		unsigned long longs[NFS4_OP_MAP_NUM_LONGS];
+		u32 words[NFS4_OP_MAP_NUM_WORDS];
+	} u;
+};
+
+struct nfs41_state_protection {
+	u32 how;
+	struct nfs4_op_map enforce;
+	struct nfs4_op_map allow;
+};
+
 #define NFS4_EXCHANGE_ID_LEN	(48)
 struct nfs41_exchange_id_args {
 	struct nfs_client		*client;
@@ -1114,6 +1131,7 @@ struct nfs41_exchange_id_args {
 	unsigned int 			id_len;
 	char 				id[NFS4_EXCHANGE_ID_LEN];
 	u32				flags;
+	struct nfs41_state_protection	state_protect;
 };
 
 struct nfs41_server_owner {
@@ -1146,6 +1164,7 @@ struct nfs41_exchange_id_res {
 	struct nfs41_server_owner	*server_owner;
 	struct nfs41_server_scope	*server_scope;
 	struct nfs41_impl_id		*impl_id;
+	struct nfs41_state_protection	state_protect;
 };
 
 struct nfs41_create_session_args {
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] nfs4.1: Add state protection handler
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 1/7] nfs4.1: Minimal " Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 3/7] nfs4.1: Add SP4_MACH_CRED cleanup support Weston Andros Adamson
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

Add nfs4_state_protect - the function responsible for switching to the machine
credential and the correct rpc client when SP4_MACH_CRED is in use.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4_fs.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index d7bb59d..77b5c9f 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -272,6 +272,35 @@ is_ds_client(struct nfs_client *clp)
 {
 	return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS;
 }
+
+/*
+ * Function responsible for determining if an rpc_message should use the
+ * machine cred under SP4_MACH_CRED and if so switching the credential and
+ * authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
+ * Should be called before rpc_call_sync/rpc_call_async.
+ */
+static inline void
+nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
+		   struct rpc_clnt **clntp, struct rpc_message *msg)
+{
+	struct rpc_cred *newcred = NULL;
+	rpc_authflavor_t flavor;
+
+	if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
+		spin_lock(&clp->cl_lock);
+		if (clp->cl_machine_cred != NULL)
+			newcred = get_rpccred(clp->cl_machine_cred);
+		spin_unlock(&clp->cl_lock);
+		if (msg->rpc_cred)
+			put_rpccred(msg->rpc_cred);
+		msg->rpc_cred = newcred;
+
+		flavor = clp->cl_rpcclient->cl_auth->au_flavor;
+		WARN_ON(flavor != RPC_AUTH_GSS_KRB5I &&
+			flavor != RPC_AUTH_GSS_KRB5P);
+		*clntp = clp->cl_rpcclient;
+	}
+}
 #else /* CONFIG_NFS_v4_1 */
 static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
 {
@@ -297,6 +326,12 @@ is_ds_client(struct nfs_client *clp)
 {
 	return false;
 }
+
+static inline void
+nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_flags,
+		   struct rpc_clnt **clntp, struct rpc_message *msg)
+{
+}
 #endif /* CONFIG_NFS_V4_1 */
 
 extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] nfs4.1: Add SP4_MACH_CRED cleanup support
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 1/7] nfs4.1: Minimal " Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 2/7] nfs4.1: Add state protection handler Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 4/7] nfs4.1: Add SP4_MACH_CRED secinfo support Weston Andros Adamson
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

CLOSE and LOCKU can use the machine credential.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4proc.c         | 19 ++++++++++++++++++-
 include/linux/nfs_fs_sb.h |  1 +
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7acf20e..76cfd0b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2511,6 +2511,9 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
 	};
 	int status = -ENOMEM;
 
+	nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
+		&task_setup_data.rpc_client, &msg);
+
 	calldata = kzalloc(sizeof(*calldata), gfp_mask);
 	if (calldata == NULL)
 		goto out;
@@ -5091,6 +5094,9 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
 		.flags = RPC_TASK_ASYNC,
 	};
 
+	nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
+		NFS_SP4_MACH_CRED_CLEANUP, &task_setup_data.rpc_client, &msg);
+
 	/* Ensure this is an unlock - when canceling a lock, the
 	 * canceled lock is passed in, and it won't be an unlock.
 	 */
@@ -5918,7 +5924,8 @@ out:
 }
 
 /*
- * Minimum set of SP4_MACH_CRED operations from RFC 5661
+ * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map
+ * and operations we'd like to see to enable certain features in the allow map
  */
 static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
 	.how = SP4_MACH_CRED,
@@ -5928,6 +5935,10 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
 		      1 << (OP_CREATE_SESSION - 32) |
 		      1 << (OP_DESTROY_SESSION - 32) |
 		      1 << (OP_DESTROY_CLIENTID - 32)
+	},
+	.allow.u.words = {
+		[0] = 1 << (OP_CLOSE) |
+		      1 << (OP_LOCKU)
 	}
 };
 
@@ -5987,6 +5998,12 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
 			dfprintk(MOUNT, "sp4_mach_cred: disabled\n");
 			return -EINVAL;
 		}
+
+		if (test_bit(OP_CLOSE, sp->allow.u.longs) &&
+		    test_bit(OP_LOCKU, sp->allow.u.longs)) {
+			dfprintk(MOUNT, "  cleanup mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags);
+		}
 	}
 
 	return 0;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index a0af429..7da24e0 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -91,6 +91,7 @@ struct nfs_client {
 	unsigned long		cl_sp4_flags;
 #define NFS_SP4_MACH_CRED_MINIMAL  1	/* Minimal sp4_mach_cred - state ops
 					 * must use machine cred */
+#define NFS_SP4_MACH_CRED_CLEANUP  2	/* CLOSE and LOCKU */
 #endif /* CONFIG_NFS_V4 */
 
 #ifdef CONFIG_NFS_FSCACHE
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] nfs4.1: Add SP4_MACH_CRED secinfo support
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
                   ` (2 preceding siblings ...)
  2013-08-13 20:37 ` [PATCH 3/7] nfs4.1: Add SP4_MACH_CRED cleanup support Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 5/7] nfs4.1: Add SP4_MACH_CRED stateid support Weston Andros Adamson
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

SECINFO and SECINFO_NONAME can use the machine credential.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4proc.c         | 15 ++++++++++++++-
 include/linux/nfs_fs_sb.h |  1 +
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 76cfd0b..b86a7b2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5820,7 +5820,12 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
 	struct rpc_clnt *clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
 
 	dprintk("NFS call  secinfo %s\n", name->name);
+
+	nfs4_state_protect(NFS_SERVER(dir)->nfs_client,
+		NFS_SP4_MACH_CRED_SECINFO, &clnt, &msg);
+
 	status = nfs4_call_sync(clnt, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);
+
 	dprintk("NFS reply  secinfo: %d\n", status);
 	return status;
 }
@@ -5938,7 +5943,9 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
 	},
 	.allow.u.words = {
 		[0] = 1 << (OP_CLOSE) |
-		      1 << (OP_LOCKU)
+		      1 << (OP_LOCKU),
+		[1] = 1 << (OP_SECINFO - 32) |
+		      1 << (OP_SECINFO_NO_NAME - 32)
 	}
 };
 
@@ -6004,6 +6011,12 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
 			dfprintk(MOUNT, "  cleanup mode enabled\n");
 			set_bit(NFS_SP4_MACH_CRED_CLEANUP, &clp->cl_sp4_flags);
 		}
+
+		if (test_bit(OP_SECINFO, sp->allow.u.longs) &&
+		    test_bit(OP_SECINFO_NO_NAME, sp->allow.u.longs)) {
+			dfprintk(MOUNT, "  secinfo mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_SECINFO, &clp->cl_sp4_flags);
+		}
 	}
 
 	return 0;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 7da24e0..0d86cec 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -92,6 +92,7 @@ struct nfs_client {
 #define NFS_SP4_MACH_CRED_MINIMAL  1	/* Minimal sp4_mach_cred - state ops
 					 * must use machine cred */
 #define NFS_SP4_MACH_CRED_CLEANUP  2	/* CLOSE and LOCKU */
+#define NFS_SP4_MACH_CRED_SECINFO  3	/* SECINFO and SECINFO_NO_NAME */
 #endif /* CONFIG_NFS_V4 */
 
 #ifdef CONFIG_NFS_FSCACHE
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] nfs4.1: Add SP4_MACH_CRED stateid support
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
                   ` (3 preceding siblings ...)
  2013-08-13 20:37 ` [PATCH 4/7] nfs4.1: Add SP4_MACH_CRED secinfo support Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 6/7] nfs4.1: Add SP4_MACH_CRED write and commit support Weston Andros Adamson
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

TEST_STATEID and FREE_STATEID can use the machine credential.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4proc.c         | 19 +++++++++++++++++--
 include/linux/nfs_fs_sb.h |  1 +
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index b86a7b2..b8e668a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5945,7 +5945,9 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
 		[0] = 1 << (OP_CLOSE) |
 		      1 << (OP_LOCKU),
 		[1] = 1 << (OP_SECINFO - 32) |
-		      1 << (OP_SECINFO_NO_NAME - 32)
+		      1 << (OP_SECINFO_NO_NAME - 32) |
+		      1 << (OP_TEST_STATEID - 32) |
+		      1 << (OP_FREE_STATEID - 32)
 	}
 };
 
@@ -6017,6 +6019,12 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
 			dfprintk(MOUNT, "  secinfo mode enabled\n");
 			set_bit(NFS_SP4_MACH_CRED_SECINFO, &clp->cl_sp4_flags);
 		}
+
+		if (test_bit(OP_TEST_STATEID, sp->allow.u.longs) &&
+		    test_bit(OP_FREE_STATEID, sp->allow.u.longs)) {
+			dfprintk(MOUNT, "  stateid mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags);
+		}
 	}
 
 	return 0;
@@ -7337,11 +7345,15 @@ static int _nfs41_test_stateid(struct nfs_server *server,
 		.rpc_resp = &res,
 		.rpc_cred = cred,
 	};
+	struct rpc_clnt *rpc_client = server->client;
+
+	nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
+		&rpc_client, &msg);
 
 	dprintk("NFS call  test_stateid %p\n", stateid);
 	nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
 	nfs4_set_sequence_privileged(&args.seq_args);
-	status = nfs4_call_sync_sequence(server->client, server, &msg,
+	status = nfs4_call_sync_sequence(rpc_client, server, &msg,
 			&args.seq_args, &res.seq_res);
 	if (status != NFS_OK) {
 		dprintk("NFS reply test_stateid: failed, %d\n", status);
@@ -7433,6 +7445,9 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
 	};
 	struct nfs_free_stateid_data *data;
 
+	nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_STATEID,
+		&task_setup.rpc_client, &msg);
+
 	dprintk("NFS call  free_stateid %p\n", stateid);
 	data = kmalloc(sizeof(*data), GFP_NOFS);
 	if (!data)
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 0d86cec..010feab 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -93,6 +93,7 @@ struct nfs_client {
 					 * must use machine cred */
 #define NFS_SP4_MACH_CRED_CLEANUP  2	/* CLOSE and LOCKU */
 #define NFS_SP4_MACH_CRED_SECINFO  3	/* SECINFO and SECINFO_NO_NAME */
+#define NFS_SP4_MACH_CRED_STATEID  4	/* TEST_STATEID and FREE_STATEID */
 #endif /* CONFIG_NFS_V4 */
 
 #ifdef CONFIG_NFS_FSCACHE
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] nfs4.1: Add SP4_MACH_CRED write and commit support
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
                   ` (4 preceding siblings ...)
  2013-08-13 20:37 ` [PATCH 5/7] nfs4.1: Add SP4_MACH_CRED stateid support Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-08-13 20:37 ` [PATCH 7/7] nfs4: Map NFS4ERR_WRONG_CRED to EPERM Weston Andros Adamson
  2013-09-03 19:12 ` [PATCH 0/7] Initial SP4_MACH_CRED implementation Adamson, Dros
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson

WRITE and COMMIT can use the machine credential.

If WRITE is supported and COMMIT is not, make all (mach cred) writes FILE_SYNC4.

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4_fs.h          | 50 ++++++++++++++++++++++++++++++++++++++---------
 fs/nfs/nfs4proc.c         | 10 ++++++++++
 fs/nfs/write.c            |  6 ++++++
 include/linux/nfs_fs_sb.h |  2 ++
 4 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 77b5c9f..2a631aa 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -273,15 +273,9 @@ is_ds_client(struct nfs_client *clp)
 	return clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_DS;
 }
 
-/*
- * Function responsible for determining if an rpc_message should use the
- * machine cred under SP4_MACH_CRED and if so switching the credential and
- * authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
- * Should be called before rpc_call_sync/rpc_call_async.
- */
-static inline void
-nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
-		   struct rpc_clnt **clntp, struct rpc_message *msg)
+static inline bool
+_nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
+		    struct rpc_clnt **clntp, struct rpc_message *msg)
 {
 	struct rpc_cred *newcred = NULL;
 	rpc_authflavor_t flavor;
@@ -299,7 +293,37 @@ nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
 		WARN_ON(flavor != RPC_AUTH_GSS_KRB5I &&
 			flavor != RPC_AUTH_GSS_KRB5P);
 		*clntp = clp->cl_rpcclient;
+
+		return true;
 	}
+	return false;
+}
+
+/*
+ * Function responsible for determining if an rpc_message should use the
+ * machine cred under SP4_MACH_CRED and if so switching the credential and
+ * authflavor (using the nfs_client's rpc_clnt which will be krb5i/p).
+ * Should be called before rpc_call_sync/rpc_call_async.
+ */
+static inline void
+nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
+		   struct rpc_clnt **clntp, struct rpc_message *msg)
+{
+	_nfs4_state_protect(clp, sp4_mode, clntp, msg);
+}
+
+/*
+ * Special wrapper to nfs4_state_protect for write.
+ * If WRITE can use machine cred but COMMIT cannot, make sure all writes
+ * that use machine cred use NFS_FILE_SYNC.
+ */
+static inline void
+nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
+			 struct rpc_message *msg, struct nfs_write_data *wdata)
+{
+	if (_nfs4_state_protect(clp, NFS_SP4_MACH_CRED_WRITE, clntp, msg) &&
+	    !test_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags))
+		wdata->args.stable = NFS_FILE_SYNC;
 }
 #else /* CONFIG_NFS_v4_1 */
 static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
@@ -332,6 +356,12 @@ nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_flags,
 		   struct rpc_clnt **clntp, struct rpc_message *msg)
 {
 }
+
+static inline void
+nfs4_state_protect_write(struct nfs_client *clp, struct rpc_clnt **clntp,
+			 struct rpc_message *msg, struct nfs_write_data *wdata)
+{
+}
 #endif /* CONFIG_NFS_V4_1 */
 
 extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
@@ -462,6 +492,8 @@ static inline bool nfs4_valid_open_stateid(const struct nfs4_state *state)
 
 #define nfs4_close_state(a, b) do { } while (0)
 #define nfs4_close_sync(a, b) do { } while (0)
+#define nfs4_state_protect(a, b, c, d) do { } while (0)
+#define nfs4_state_protect_write(a, b, c, d) do { } while (0)
 
 #endif /* CONFIG_NFS_V4 */
 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index b8e668a..1e8a4c0 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6025,6 +6025,16 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
 			dfprintk(MOUNT, "  stateid mode enabled\n");
 			set_bit(NFS_SP4_MACH_CRED_STATEID, &clp->cl_sp4_flags);
 		}
+
+		if (test_bit(OP_WRITE, sp->allow.u.longs)) {
+			dfprintk(MOUNT, "  write mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_WRITE, &clp->cl_sp4_flags);
+		}
+
+		if (test_bit(OP_COMMIT, sp->allow.u.longs)) {
+			dfprintk(MOUNT, "  commit mode enabled\n");
+			set_bit(NFS_SP4_MACH_CRED_COMMIT, &clp->cl_sp4_flags);
+		}
 	}
 
 	return 0;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f1bdb72..0ff6dfe 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -993,6 +993,9 @@ int nfs_initiate_write(struct rpc_clnt *clnt,
 		data->args.count,
 		(unsigned long long)data->args.offset);
 
+	nfs4_state_protect_write(NFS_SERVER(inode)->nfs_client,
+				 &task_setup_data.rpc_client, &msg, data);
+
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task)) {
 		ret = PTR_ERR(task);
@@ -1458,6 +1461,9 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
 
 	dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
 
+	nfs4_state_protect(NFS_SERVER(data->inode)->nfs_client,
+		NFS_SP4_MACH_CRED_COMMIT, &task_setup_data.rpc_client, &msg);
+
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 010feab..f2aa366 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -94,6 +94,8 @@ struct nfs_client {
 #define NFS_SP4_MACH_CRED_CLEANUP  2	/* CLOSE and LOCKU */
 #define NFS_SP4_MACH_CRED_SECINFO  3	/* SECINFO and SECINFO_NO_NAME */
 #define NFS_SP4_MACH_CRED_STATEID  4	/* TEST_STATEID and FREE_STATEID */
+#define NFS_SP4_MACH_CRED_WRITE    5	/* WRITE */
+#define NFS_SP4_MACH_CRED_COMMIT   6	/* COMMIT */
 #endif /* CONFIG_NFS_V4 */
 
 #ifdef CONFIG_NFS_FSCACHE
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] nfs4: Map NFS4ERR_WRONG_CRED to EPERM
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
                   ` (5 preceding siblings ...)
  2013-08-13 20:37 ` [PATCH 6/7] nfs4.1: Add SP4_MACH_CRED write and commit support Weston Andros Adamson
@ 2013-08-13 20:37 ` Weston Andros Adamson
  2013-09-03 19:12 ` [PATCH 0/7] Initial SP4_MACH_CRED implementation Adamson, Dros
  7 siblings, 0 replies; 9+ messages in thread
From: Weston Andros Adamson @ 2013-08-13 20:37 UTC (permalink / raw)
  To: Trond.Myklebust; +Cc: linux-nfs, Weston Andros Adamson


Signed-off-by: Weston Andros Adamson <dros@netapp.com>
---
 fs/nfs/nfs4proc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1e8a4c0..d41935f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -150,6 +150,7 @@ static int nfs4_map_errors(int err)
 	case -NFS4ERR_RECALLCONFLICT:
 		return -EREMOTEIO;
 	case -NFS4ERR_WRONGSEC:
+	case -NFS4ERR_WRONG_CRED:
 		return -EPERM;
 	case -NFS4ERR_BADOWNER:
 	case -NFS4ERR_BADNAME:
-- 
1.7.12.4 (Apple Git-37)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/7] Initial SP4_MACH_CRED implementation
  2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
                   ` (6 preceding siblings ...)
  2013-08-13 20:37 ` [PATCH 7/7] nfs4: Map NFS4ERR_WRONG_CRED to EPERM Weston Andros Adamson
@ 2013-09-03 19:12 ` Adamson, Dros
  7 siblings, 0 replies; 9+ messages in thread
From: Adamson, Dros @ 2013-09-03 19:12 UTC (permalink / raw)
  To: Myklebust, Trond; +Cc: <linux-nfs@vger.kernel.org>

Trond,

I think that these patches are missing put_rpccred() calls when we change rpc_message.

I'll add and repost…

-dros

On Aug 13, 2013, at 4:37 PM, Weston Andros Adamson <dros@netapp.com> wrote:

> This is version 2 of this patchset including some cleanup, refactoring and
> fixes a few build issues with different configs.
> 
> I also added a few patches:
> - WRITE and/or COMMIT support - tested on a hacked nfsd
> - map NFS4ERR_WRONG_CRED (an common SP4 error) to EPERM
> 
> I meant to include a patch that only uses the machine cred (for 'allow' ops)
> when the user cred has expired, but after talking with Andy, I decided to wait
> for his cred expiration patchset to be merged as we'd be touching the same
> places and possibly duplicating effort.
> 
> Weston Andros Adamson (7):
>  nfs4.1: Minimal SP4_MACH_CRED implementation
>  nfs4.1: Add state protection handler
>  nfs4.1: Add SP4_MACH_CRED cleanup support
>  nfs4.1: Add SP4_MACH_CRED secinfo support
>  nfs4.1: Add SP4_MACH_CRED stateid support
>  nfs4.1: Add SP4_MACH_CRED write and commit support
>  nfs4: Map NFS4ERR_WRONG_CRED to EPERM
> 
> fs/nfs/nfs4_fs.h          |  67 ++++++++++++++++
> fs/nfs/nfs4proc.c         | 191 ++++++++++++++++++++++++++++++++++++++++++++--
> fs/nfs/nfs4xdr.c          |  72 ++++++++++++++---
> fs/nfs/write.c            |   6 ++
> include/linux/nfs_fs_sb.h |   9 +++
> include/linux/nfs_xdr.h   |  19 +++++
> 6 files changed, 346 insertions(+), 18 deletions(-)
> 
> -- 
> 1.7.12.4 (Apple Git-37)
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-09-03 19:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-13 20:37 [PATCH 0/7] Initial SP4_MACH_CRED implementation Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 1/7] nfs4.1: Minimal " Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 2/7] nfs4.1: Add state protection handler Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 3/7] nfs4.1: Add SP4_MACH_CRED cleanup support Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 4/7] nfs4.1: Add SP4_MACH_CRED secinfo support Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 5/7] nfs4.1: Add SP4_MACH_CRED stateid support Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 6/7] nfs4.1: Add SP4_MACH_CRED write and commit support Weston Andros Adamson
2013-08-13 20:37 ` [PATCH 7/7] nfs4: Map NFS4ERR_WRONG_CRED to EPERM Weston Andros Adamson
2013-09-03 19:12 ` [PATCH 0/7] Initial SP4_MACH_CRED implementation Adamson, Dros

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).