aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/callback.h19
-rw-r--r--fs/nfs/callback_proc.c6
-rw-r--r--fs/nfs/callback_xdr.c69
3 files changed, 93 insertions, 1 deletions
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index b678e3e15bd9..f6768ac09190 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -138,6 +138,25 @@ extern __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args,
138 void *dummy, 138 void *dummy,
139 struct cb_process_state *cps); 139 struct cb_process_state *cps);
140 140
141struct cb_layoutrecallargs {
142 struct sockaddr *cbl_addr;
143 uint32_t cbl_recall_type;
144 uint32_t cbl_layout_type;
145 uint32_t cbl_layoutchanged;
146 union {
147 struct {
148 struct nfs_fh cbl_fh;
149 struct pnfs_layout_range cbl_range;
150 nfs4_stateid cbl_stateid;
151 };
152 struct nfs_fsid cbl_fsid;
153 };
154};
155
156extern unsigned nfs4_callback_layoutrecall(
157 struct cb_layoutrecallargs *args,
158 void *dummy, struct cb_process_state *cps);
159
141extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); 160extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
142extern void nfs4_cb_take_slot(struct nfs_client *clp); 161extern void nfs4_cb_take_slot(struct nfs_client *clp);
143#endif /* CONFIG_NFS_V4_1 */ 162#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index c1bead2f3e04..c1bb157e94bd 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -107,6 +107,12 @@ int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nf
107 107
108#if defined(CONFIG_NFS_V4_1) 108#if defined(CONFIG_NFS_V4_1)
109 109
110__be32 nfs4_callback_layoutrecall(struct cb_layoutrecallargs *args,
111 void *dummy, struct cb_process_state *cps)
112{
113 return cpu_to_be32(NFS4ERR_NOTSUPP); /* STUB */
114}
115
110int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) 116int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid)
111{ 117{
112 if (delegation == NULL) 118 if (delegation == NULL)
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 7a2d6c5864ca..23112c263f81 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -24,6 +24,7 @@
24#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 24#define CB_OP_RECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
25 25
26#if defined(CONFIG_NFS_V4_1) 26#if defined(CONFIG_NFS_V4_1)
27#define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
27#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 28#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
28 4 + 1 + 3) 29 4 + 1 + 3)
29#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) 30#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
@@ -223,6 +224,66 @@ out:
223 224
224#if defined(CONFIG_NFS_V4_1) 225#if defined(CONFIG_NFS_V4_1)
225 226
227static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
228 struct xdr_stream *xdr,
229 struct cb_layoutrecallargs *args)
230{
231 __be32 *p;
232 __be32 status = 0;
233 uint32_t iomode;
234
235 args->cbl_addr = svc_addr(rqstp);
236 p = read_buf(xdr, 4 * sizeof(uint32_t));
237 if (unlikely(p == NULL)) {
238 status = htonl(NFS4ERR_BADXDR);
239 goto out;
240 }
241
242 args->cbl_layout_type = ntohl(*p++);
243 /* Depite the spec's xdr, iomode really belongs in the FILE switch,
244 * as it is unuseable and ignored with the other types.
245 */
246 iomode = ntohl(*p++);
247 args->cbl_layoutchanged = ntohl(*p++);
248 args->cbl_recall_type = ntohl(*p++);
249
250 if (args->cbl_recall_type == RETURN_FILE) {
251 args->cbl_range.iomode = iomode;
252 status = decode_fh(xdr, &args->cbl_fh);
253 if (unlikely(status != 0))
254 goto out;
255
256 p = read_buf(xdr, 2 * sizeof(uint64_t));
257 if (unlikely(p == NULL)) {
258 status = htonl(NFS4ERR_BADXDR);
259 goto out;
260 }
261 p = xdr_decode_hyper(p, &args->cbl_range.offset);
262 p = xdr_decode_hyper(p, &args->cbl_range.length);
263 status = decode_stateid(xdr, &args->cbl_stateid);
264 if (unlikely(status != 0))
265 goto out;
266 } else if (args->cbl_recall_type == RETURN_FSID) {
267 p = read_buf(xdr, 2 * sizeof(uint64_t));
268 if (unlikely(p == NULL)) {
269 status = htonl(NFS4ERR_BADXDR);
270 goto out;
271 }
272 p = xdr_decode_hyper(p, &args->cbl_fsid.major);
273 p = xdr_decode_hyper(p, &args->cbl_fsid.minor);
274 } else if (args->cbl_recall_type != RETURN_ALL) {
275 status = htonl(NFS4ERR_BADXDR);
276 goto out;
277 }
278 dprintk("%s: ltype 0x%x iomode %d changed %d recall_type %d\n",
279 __func__,
280 args->cbl_layout_type, iomode,
281 args->cbl_layoutchanged, args->cbl_recall_type);
282out:
283 dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
284 return status;
285}
286
226static __be32 decode_sessionid(struct xdr_stream *xdr, 287static __be32 decode_sessionid(struct xdr_stream *xdr,
227 struct nfs4_sessionid *sid) 288 struct nfs4_sessionid *sid)
228{ 289{
@@ -577,10 +638,10 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
577 case OP_CB_SEQUENCE: 638 case OP_CB_SEQUENCE:
578 case OP_CB_RECALL_ANY: 639 case OP_CB_RECALL_ANY:
579 case OP_CB_RECALL_SLOT: 640 case OP_CB_RECALL_SLOT:
641 case OP_CB_LAYOUTRECALL:
580 *op = &callback_ops[op_nr]; 642 *op = &callback_ops[op_nr];
581 break; 643 break;
582 644
583 case OP_CB_LAYOUTRECALL:
584 case OP_CB_NOTIFY_DEVICEID: 645 case OP_CB_NOTIFY_DEVICEID:
585 case OP_CB_NOTIFY: 646 case OP_CB_NOTIFY:
586 case OP_CB_PUSH_DELEG: 647 case OP_CB_PUSH_DELEG:
@@ -783,6 +844,12 @@ static struct callback_op callback_ops[] = {
783 .res_maxsize = CB_OP_RECALL_RES_MAXSZ, 844 .res_maxsize = CB_OP_RECALL_RES_MAXSZ,
784 }, 845 },
785#if defined(CONFIG_NFS_V4_1) 846#if defined(CONFIG_NFS_V4_1)
847 [OP_CB_LAYOUTRECALL] = {
848 .process_op = (callback_process_op_t)nfs4_callback_layoutrecall,
849 .decode_args =
850 (callback_decode_arg_t)decode_layoutrecall_args,
851 .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ,
852 },
786 [OP_CB_SEQUENCE] = { 853 [OP_CB_SEQUENCE] = {
787 .process_op = (callback_process_op_t)nfs4_callback_sequence, 854 .process_op = (callback_process_op_t)nfs4_callback_sequence,
788 .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, 855 .decode_args = (callback_decode_arg_t)decode_cb_sequence_args,