diff options
| -rw-r--r-- | fs/nfs/nfs4proc.c | 42 | ||||
| -rw-r--r-- | fs/nfs/nfs4session.h | 6 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 16 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 8 |
4 files changed, 49 insertions, 23 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2e7c9f7a6f7c..006bfa3da55b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -7166,10 +7166,11 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) | |||
| 7166 | args->bc_attrs.max_reqs); | 7166 | args->bc_attrs.max_reqs); |
| 7167 | } | 7167 | } |
| 7168 | 7168 | ||
| 7169 | static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args, struct nfs4_session *session) | 7169 | static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args, |
| 7170 | struct nfs41_create_session_res *res) | ||
| 7170 | { | 7171 | { |
| 7171 | struct nfs4_channel_attrs *sent = &args->fc_attrs; | 7172 | struct nfs4_channel_attrs *sent = &args->fc_attrs; |
| 7172 | struct nfs4_channel_attrs *rcvd = &session->fc_attrs; | 7173 | struct nfs4_channel_attrs *rcvd = &res->fc_attrs; |
| 7173 | 7174 | ||
| 7174 | if (rcvd->max_resp_sz > sent->max_resp_sz) | 7175 | if (rcvd->max_resp_sz > sent->max_resp_sz) |
| 7175 | return -EINVAL; | 7176 | return -EINVAL; |
| @@ -7188,10 +7189,11 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args | |||
| 7188 | return 0; | 7189 | return 0; |
| 7189 | } | 7190 | } |
| 7190 | 7191 | ||
| 7191 | static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, struct nfs4_session *session) | 7192 | static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args, |
| 7193 | struct nfs41_create_session_res *res) | ||
| 7192 | { | 7194 | { |
| 7193 | struct nfs4_channel_attrs *sent = &args->bc_attrs; | 7195 | struct nfs4_channel_attrs *sent = &args->bc_attrs; |
| 7194 | struct nfs4_channel_attrs *rcvd = &session->bc_attrs; | 7196 | struct nfs4_channel_attrs *rcvd = &res->bc_attrs; |
| 7195 | 7197 | ||
| 7196 | if (rcvd->max_rqst_sz > sent->max_rqst_sz) | 7198 | if (rcvd->max_rqst_sz > sent->max_rqst_sz) |
| 7197 | return -EINVAL; | 7199 | return -EINVAL; |
| @@ -7208,14 +7210,23 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args | |||
| 7208 | } | 7210 | } |
| 7209 | 7211 | ||
| 7210 | static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, | 7212 | static int nfs4_verify_channel_attrs(struct nfs41_create_session_args *args, |
| 7211 | struct nfs4_session *session) | 7213 | struct nfs41_create_session_res *res) |
| 7212 | { | 7214 | { |
| 7213 | int ret; | 7215 | int ret; |
| 7214 | 7216 | ||
| 7215 | ret = nfs4_verify_fore_channel_attrs(args, session); | 7217 | ret = nfs4_verify_fore_channel_attrs(args, res); |
| 7216 | if (ret) | 7218 | if (ret) |
| 7217 | return ret; | 7219 | return ret; |
| 7218 | return nfs4_verify_back_channel_attrs(args, session); | 7220 | return nfs4_verify_back_channel_attrs(args, res); |
| 7221 | } | ||
| 7222 | |||
| 7223 | static void nfs4_update_session(struct nfs4_session *session, | ||
| 7224 | struct nfs41_create_session_res *res) | ||
| 7225 | { | ||
| 7226 | nfs4_copy_sessionid(&session->sess_id, &res->sessionid); | ||
| 7227 | session->flags = res->flags; | ||
| 7228 | memcpy(&session->fc_attrs, &res->fc_attrs, sizeof(session->fc_attrs)); | ||
| 7229 | memcpy(&session->bc_attrs, &res->bc_attrs, sizeof(session->bc_attrs)); | ||
| 7219 | } | 7230 | } |
| 7220 | 7231 | ||
| 7221 | static int _nfs4_proc_create_session(struct nfs_client *clp, | 7232 | static int _nfs4_proc_create_session(struct nfs_client *clp, |
| @@ -7224,11 +7235,12 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
| 7224 | struct nfs4_session *session = clp->cl_session; | 7235 | struct nfs4_session *session = clp->cl_session; |
| 7225 | struct nfs41_create_session_args args = { | 7236 | struct nfs41_create_session_args args = { |
| 7226 | .client = clp, | 7237 | .client = clp, |
| 7238 | .clientid = clp->cl_clientid, | ||
| 7239 | .seqid = clp->cl_seqid, | ||
| 7227 | .cb_program = NFS4_CALLBACK, | 7240 | .cb_program = NFS4_CALLBACK, |
| 7228 | }; | 7241 | }; |
| 7229 | struct nfs41_create_session_res res = { | 7242 | struct nfs41_create_session_res res; |
| 7230 | .client = clp, | 7243 | |
| 7231 | }; | ||
| 7232 | struct rpc_message msg = { | 7244 | struct rpc_message msg = { |
| 7233 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], | 7245 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE_SESSION], |
| 7234 | .rpc_argp = &args, | 7246 | .rpc_argp = &args, |
| @@ -7245,11 +7257,15 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
| 7245 | 7257 | ||
| 7246 | if (!status) { | 7258 | if (!status) { |
| 7247 | /* Verify the session's negotiated channel_attrs values */ | 7259 | /* Verify the session's negotiated channel_attrs values */ |
| 7248 | status = nfs4_verify_channel_attrs(&args, session); | 7260 | status = nfs4_verify_channel_attrs(&args, &res); |
| 7249 | /* Increment the clientid slot sequence id */ | 7261 | /* Increment the clientid slot sequence id */ |
| 7250 | clp->cl_seqid++; | 7262 | if (clp->cl_seqid == res.seqid) |
| 7263 | clp->cl_seqid++; | ||
| 7264 | if (status) | ||
| 7265 | goto out; | ||
| 7266 | nfs4_update_session(session, &res); | ||
| 7251 | } | 7267 | } |
| 7252 | 7268 | out: | |
| 7253 | return status; | 7269 | return status; |
| 7254 | } | 7270 | } |
| 7255 | 7271 | ||
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index b34ada9bc6a2..fc46c7455898 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h | |||
| @@ -118,6 +118,12 @@ static inline int nfs4_has_persistent_session(const struct nfs_client *clp) | |||
| 118 | return 0; | 118 | return 0; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | static inline void nfs4_copy_sessionid(struct nfs4_sessionid *dst, | ||
| 122 | const struct nfs4_sessionid *src) | ||
| 123 | { | ||
| 124 | memcpy(dst->data, src->data, NFS4_MAX_SESSIONID_LEN); | ||
| 125 | } | ||
| 126 | |||
| 121 | #ifdef CONFIG_CRC32 | 127 | #ifdef CONFIG_CRC32 |
| 122 | /* | 128 | /* |
| 123 | * nfs_session_id_hash - calculate the crc32 hash for the session id | 129 | * nfs_session_id_hash - calculate the crc32 hash for the session id |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e23a0a664e12..248903b138a8 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -1806,8 +1806,8 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
| 1806 | 1806 | ||
| 1807 | encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); | 1807 | encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); |
| 1808 | p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); | 1808 | p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); |
| 1809 | p = xdr_encode_hyper(p, clp->cl_clientid); | 1809 | p = xdr_encode_hyper(p, args->clientid); |
| 1810 | *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ | 1810 | *p++ = cpu_to_be32(args->seqid); /*Sequence id */ |
| 1811 | *p++ = cpu_to_be32(args->flags); /*flags */ | 1811 | *p++ = cpu_to_be32(args->flags); /*flags */ |
| 1812 | 1812 | ||
| 1813 | /* Fore Channel */ | 1813 | /* Fore Channel */ |
| @@ -5641,12 +5641,10 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
| 5641 | { | 5641 | { |
| 5642 | __be32 *p; | 5642 | __be32 *p; |
| 5643 | int status; | 5643 | int status; |
| 5644 | struct nfs_client *clp = res->client; | ||
| 5645 | struct nfs4_session *session = clp->cl_session; | ||
| 5646 | 5644 | ||
| 5647 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); | 5645 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); |
| 5648 | if (!status) | 5646 | if (!status) |
| 5649 | status = decode_sessionid(xdr, &session->sess_id); | 5647 | status = decode_sessionid(xdr, &res->sessionid); |
| 5650 | if (unlikely(status)) | 5648 | if (unlikely(status)) |
| 5651 | return status; | 5649 | return status; |
| 5652 | 5650 | ||
| @@ -5654,13 +5652,13 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
| 5654 | p = xdr_inline_decode(xdr, 8); | 5652 | p = xdr_inline_decode(xdr, 8); |
| 5655 | if (unlikely(!p)) | 5653 | if (unlikely(!p)) |
| 5656 | goto out_overflow; | 5654 | goto out_overflow; |
| 5657 | clp->cl_seqid = be32_to_cpup(p++); | 5655 | res->seqid = be32_to_cpup(p++); |
| 5658 | session->flags = be32_to_cpup(p); | 5656 | res->flags = be32_to_cpup(p); |
| 5659 | 5657 | ||
| 5660 | /* Channel attributes */ | 5658 | /* Channel attributes */ |
| 5661 | status = decode_chan_attrs(xdr, &session->fc_attrs); | 5659 | status = decode_chan_attrs(xdr, &res->fc_attrs); |
| 5662 | if (!status) | 5660 | if (!status) |
| 5663 | status = decode_chan_attrs(xdr, &session->bc_attrs); | 5661 | status = decode_chan_attrs(xdr, &res->bc_attrs); |
| 5664 | return status; | 5662 | return status; |
| 5665 | out_overflow: | 5663 | out_overflow: |
| 5666 | print_overflow_msg(__func__, xdr); | 5664 | print_overflow_msg(__func__, xdr); |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9a39132fda49..1af12fc16e98 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -1185,6 +1185,8 @@ struct nfs41_exchange_id_res { | |||
| 1185 | 1185 | ||
| 1186 | struct nfs41_create_session_args { | 1186 | struct nfs41_create_session_args { |
| 1187 | struct nfs_client *client; | 1187 | struct nfs_client *client; |
| 1188 | u64 clientid; | ||
| 1189 | uint32_t seqid; | ||
| 1188 | uint32_t flags; | 1190 | uint32_t flags; |
| 1189 | uint32_t cb_program; | 1191 | uint32_t cb_program; |
| 1190 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ | 1192 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ |
| @@ -1192,7 +1194,11 @@ struct nfs41_create_session_args { | |||
| 1192 | }; | 1194 | }; |
| 1193 | 1195 | ||
| 1194 | struct nfs41_create_session_res { | 1196 | struct nfs41_create_session_res { |
| 1195 | struct nfs_client *client; | 1197 | struct nfs4_sessionid sessionid; |
| 1198 | uint32_t seqid; | ||
| 1199 | uint32_t flags; | ||
| 1200 | struct nfs4_channel_attrs fc_attrs; /* Fore Channel */ | ||
| 1201 | struct nfs4_channel_attrs bc_attrs; /* Back Channel */ | ||
| 1196 | }; | 1202 | }; |
| 1197 | 1203 | ||
| 1198 | struct nfs41_reclaim_complete_args { | 1204 | struct nfs41_reclaim_complete_args { |
