nfs4.1: Minimal SP4_MACH_CRED implementation
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> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
		
					parent
					
						
							
								92cb6c5be8
							
						
					
				
			
			
				commit
				
					
						2031cd1af1
					
				
			
		
					 4 changed files with 213 additions and 19 deletions
				
			
		| 
						 | 
					@ -6117,16 +6117,87 @@ out:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * nfs4_proc_exchange_id()
 | 
					 * Minimum set of SP4_MACH_CRED operations from RFC 5661
 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 | 
					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 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()
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Wrapper for EXCHANGE_ID operation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
 | 
				
			||||||
 | 
						u32 sp4_how)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nfs4_verifier verifier;
 | 
						nfs4_verifier verifier;
 | 
				
			||||||
	struct nfs41_exchange_id_args args = {
 | 
						struct nfs41_exchange_id_args args = {
 | 
				
			||||||
| 
						 | 
					@ -6173,11 +6244,30 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 | 
				
			||||||
		goto out_server_scope;
 | 
							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);
 | 
						status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 | 
				
			||||||
	trace_nfs4_exchange_id(clp, status);
 | 
						trace_nfs4_exchange_id(clp, status);
 | 
				
			||||||
	if (status == 0)
 | 
						if (status == 0)
 | 
				
			||||||
		status = nfs4_check_cl_exchange_flags(res.flags);
 | 
							status = nfs4_check_cl_exchange_flags(res.flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (status == 0)
 | 
				
			||||||
 | 
							status = nfs4_sp4_select_mode(clp, &res.state_protect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status == 0) {
 | 
						if (status == 0) {
 | 
				
			||||||
		clp->cl_clientid = res.clientid;
 | 
							clp->cl_clientid = res.clientid;
 | 
				
			||||||
		clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
 | 
							clp->cl_exchange_flags = (res.flags & ~EXCHGID4_FLAG_CONFIRMED_R);
 | 
				
			||||||
| 
						 | 
					@ -6224,6 +6314,35 @@ out:
 | 
				
			||||||
	return status;
 | 
						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,
 | 
					static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 | 
				
			||||||
		struct rpc_cred *cred)
 | 
							struct rpc_cred *cred)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,7 +294,9 @@ static int nfs4_stat_to_errno(int);
 | 
				
			||||||
				XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
 | 
									XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
 | 
				
			||||||
				1 /* flags */ + \
 | 
									1 /* flags */ + \
 | 
				
			||||||
				1 /* spa_how */ + \
 | 
									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 /* implementation id array of size 1 */ + \
 | 
				
			||||||
				1 /* nii_domain */ + \
 | 
									1 /* nii_domain */ + \
 | 
				
			||||||
				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
 | 
									XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
 | 
				
			||||||
| 
						 | 
					@ -306,7 +308,9 @@ static int nfs4_stat_to_errno(int);
 | 
				
			||||||
				1 /* eir_sequenceid */ + \
 | 
									1 /* eir_sequenceid */ + \
 | 
				
			||||||
				1 /* eir_flags */ + \
 | 
									1 /* eir_flags */ + \
 | 
				
			||||||
				1 /* spr_how */ + \
 | 
									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 */ + \
 | 
									2 /* eir_server_owner.so_minor_id */ + \
 | 
				
			||||||
				/* eir_server_owner.so_major_id<> */ \
 | 
									/* eir_server_owner.so_major_id<> */ \
 | 
				
			||||||
				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
 | 
									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 */
 | 
						*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,
 | 
					static void encode_exchange_id(struct xdr_stream *xdr,
 | 
				
			||||||
			       struct nfs41_exchange_id_args *args,
 | 
								       struct nfs41_exchange_id_args *args,
 | 
				
			||||||
			       struct compound_hdr *hdr)
 | 
								       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);
 | 
						encode_string(xdr, args->id_len, args->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p = reserve_space(xdr, 12);
 | 
						encode_uint32(xdr, args->flags);
 | 
				
			||||||
	*p++ = cpu_to_be32(args->flags);
 | 
						encode_uint32(xdr, args->state_protect.how);
 | 
				
			||||||
	*p++ = cpu_to_be32(0);	/* zero length state_protect4_a */
 | 
					
 | 
				
			||||||
 | 
						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 &&
 | 
						if (send_implementation_id &&
 | 
				
			||||||
	    sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
 | 
						    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);
 | 
								       utsname()->version, utsname()->machine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (len > 0) {
 | 
						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,
 | 
							encode_string(xdr,
 | 
				
			||||||
			sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
 | 
								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 = xdr_encode_hyper(p, 0);
 | 
				
			||||||
		*p = cpu_to_be32(0);
 | 
							*p = cpu_to_be32(0);
 | 
				
			||||||
	} else
 | 
						} 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,
 | 
					static void encode_create_session(struct xdr_stream *xdr,
 | 
				
			||||||
| 
						 | 
					@ -5374,6 +5397,23 @@ static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_re
 | 
				
			||||||
	return decode_secinfo_common(xdr, res);
 | 
						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,
 | 
					static int decode_exchange_id(struct xdr_stream *xdr,
 | 
				
			||||||
			      struct nfs41_exchange_id_res *res)
 | 
								      struct nfs41_exchange_id_res *res)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -5397,10 +5437,22 @@ static int decode_exchange_id(struct xdr_stream *xdr,
 | 
				
			||||||
	res->seqid = be32_to_cpup(p++);
 | 
						res->seqid = be32_to_cpup(p++);
 | 
				
			||||||
	res->flags = be32_to_cpup(p++);
 | 
						res->flags = be32_to_cpup(p++);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We ask for SP4_NONE */
 | 
						res->state_protect.how = be32_to_cpup(p);
 | 
				
			||||||
	dummy = be32_to_cpup(p);
 | 
						switch (res->state_protect.how) {
 | 
				
			||||||
	if (dummy != SP4_NONE)
 | 
						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;
 | 
							return -EIO;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* server_owner4.so_minor_id */
 | 
						/* server_owner4.so_minor_id */
 | 
				
			||||||
	p = xdr_inline_decode(xdr, 8);
 | 
						p = xdr_inline_decode(xdr, 8);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,6 +90,10 @@ struct nfs_client {
 | 
				
			||||||
	struct nfs41_server_owner *cl_serverowner;
 | 
						struct nfs41_server_owner *cl_serverowner;
 | 
				
			||||||
	struct nfs41_server_scope *cl_serverscope;
 | 
						struct nfs41_server_scope *cl_serverscope;
 | 
				
			||||||
	struct nfs41_impl_id	*cl_implid;
 | 
						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 */
 | 
					#endif /* CONFIG_NFS_V4 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_NFS_FSCACHE
 | 
					#ifdef CONFIG_NFS_FSCACHE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1107,6 +1107,23 @@ struct pnfs_ds_commit_info {
 | 
				
			||||||
	struct pnfs_commit_bucket *buckets;
 | 
						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)
 | 
					#define NFS4_EXCHANGE_ID_LEN	(48)
 | 
				
			||||||
struct nfs41_exchange_id_args {
 | 
					struct nfs41_exchange_id_args {
 | 
				
			||||||
	struct nfs_client		*client;
 | 
						struct nfs_client		*client;
 | 
				
			||||||
| 
						 | 
					@ -1114,6 +1131,7 @@ struct nfs41_exchange_id_args {
 | 
				
			||||||
	unsigned int 			id_len;
 | 
						unsigned int 			id_len;
 | 
				
			||||||
	char 				id[NFS4_EXCHANGE_ID_LEN];
 | 
						char 				id[NFS4_EXCHANGE_ID_LEN];
 | 
				
			||||||
	u32				flags;
 | 
						u32				flags;
 | 
				
			||||||
 | 
						struct nfs41_state_protection	state_protect;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct nfs41_server_owner {
 | 
					struct nfs41_server_owner {
 | 
				
			||||||
| 
						 | 
					@ -1146,6 +1164,7 @@ struct nfs41_exchange_id_res {
 | 
				
			||||||
	struct nfs41_server_owner	*server_owner;
 | 
						struct nfs41_server_owner	*server_owner;
 | 
				
			||||||
	struct nfs41_server_scope	*server_scope;
 | 
						struct nfs41_server_scope	*server_scope;
 | 
				
			||||||
	struct nfs41_impl_id		*impl_id;
 | 
						struct nfs41_impl_id		*impl_id;
 | 
				
			||||||
 | 
						struct nfs41_state_protection	state_protect;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct nfs41_create_session_args {
 | 
					struct nfs41_create_session_args {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue