[PATCH 2/3] SQUASHME: nfs41: refactor op preprocessing out of process_op

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fixes Trond's review comment from 2009-06-15:
Re: [pnfs] [RFC 27/39] nfs41: consider minorversion in callback_xdr:process_op
http://linux-nfs.org/pipermail/pnfs/2009-June/007845.html

Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx>
---
 fs/nfs/callback_xdr.c |  119 +++++++++++++++++++++++++++---------------------
 1 files changed, 67 insertions(+), 52 deletions(-)

diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 654a6a2..28242a0 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -523,8 +523,67 @@ out:
 	return status;
 }
 
+static __be32
+preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
+{
+	if (op_nr == OP_CB_SEQUENCE) {
+		if (nop != 0)
+			return htonl(NFS4ERR_SEQUENCE_POS);
+	} else {
+		if (nop == 0)
+			return htonl(NFS4ERR_OP_NOT_IN_SESSION);
+	}
+
+	switch (op_nr) {
+	case OP_CB_GETATTR:
+	case OP_CB_RECALL:
+	case OP_CB_SEQUENCE:
+		*op = &callback_ops[op_nr];
+		break;
+
+	case OP_CB_LAYOUTRECALL:
+	case OP_CB_NOTIFY_DEVICEID:
+	case OP_CB_NOTIFY:
+	case OP_CB_PUSH_DELEG:
+	case OP_CB_RECALL_ANY:
+	case OP_CB_RECALLABLE_OBJ_AVAIL:
+	case OP_CB_RECALL_SLOT:
+	case OP_CB_WANTS_CANCELLED:
+	case OP_CB_NOTIFY_LOCK:
+		return htonl(NFS4ERR_NOTSUPP);
+
+	default:
+		return htonl(NFS4ERR_OP_ILLEGAL);
+	}
+
+	return htonl(NFS_OK);
+}
+
+#else /* CONFIG_NFS_V4_1 */
+
+static __be32
+preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
+{
+	return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
+}
+
 #endif /* CONFIG_NFS_V4_1 */
 
+static __be32
+preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
+{
+	switch (op_nr) {
+	case OP_CB_GETATTR:
+	case OP_CB_RECALL:
+		*op = &callback_ops[op_nr];
+		break;
+	default:
+		return htonl(NFS4ERR_OP_ILLEGAL);
+	}
+
+	return htonl(NFS_OK);
+}
+
 static __be32 process_op(uint32_t minorversion, int nop,
 		struct svc_rqst *rqstp,
 		struct xdr_stream *xdr_in, void *argp,
@@ -538,56 +597,18 @@ static __be32 process_op(uint32_t minorversion, int nop,
 
 	dprintk("%s: start\n", __func__);
 	status = decode_op_hdr(xdr_in, &op_nr);
-	if (unlikely(status))
-		goto out_illegal;
+	if (unlikely(status)) {
+		status = htonl(NFS4ERR_OP_ILLEGAL);
+		goto out;
+	}
 
 	dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
 		__func__, minorversion, nop, op_nr);
-#if defined(CONFIG_NFS_V4_1)
-	if (minorversion == 1) {
-		if (op_nr == OP_CB_SEQUENCE) {
-			if (nop != 0) {
-				status = htonl(NFS4ERR_SEQUENCE_POS);
-				goto out;
-			}
-		} else if (nop == 0)
-			status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
-
-		switch (op_nr) {
-		case OP_CB_GETATTR:
-		case OP_CB_RECALL:
-		case OP_CB_SEQUENCE:
-			op = &callback_ops[op_nr];
-			break;
-
-		case OP_CB_LAYOUTRECALL:
-		case OP_CB_NOTIFY:
-		case OP_CB_PUSH_DELEG:
-		case OP_CB_RECALL_ANY:
-		case OP_CB_RECALLABLE_OBJ_AVAIL:
-		case OP_CB_RECALL_SLOT:
-		case OP_CB_WANTS_CANCELLED:
-		case OP_CB_NOTIFY_LOCK:
-		case OP_CB_NOTIFY_DEVICEID:
-			op = &callback_ops[0];
-			status = htonl(NFS4ERR_NOTSUPP);
-			break;
-		default:
-			goto out_illegal;
-		}
 
-		goto out;
-	}
-#endif /* defined(CONFIG_NFS_V4_1) */
-
-	switch (op_nr) {
-	case OP_CB_GETATTR:
-	case OP_CB_RECALL:
-		op = &callback_ops[op_nr];
-		break;
-	default:
-		goto out_illegal;
-	}
+	status = minorversion ? preprocess_nfs41_op(nop, op_nr, &op) :
+				preprocess_nfs4_op(op_nr, &op);
+	if (status == htonl(NFS4ERR_OP_ILLEGAL))
+		op_nr = OP_CB_ILLEGAL;
 out:
 	maxlen = xdr_out->end - xdr_out->p;
 	if (maxlen > 0 && maxlen < PAGE_SIZE) {
@@ -605,12 +626,6 @@ out:
 		status = op->encode_res(rqstp, xdr_out, resp);
 	dprintk("%s: done, status = %d\n", __func__, ntohl(status));
 	return status;
-
-out_illegal:
-	op_nr = OP_CB_ILLEGAL;
-	op = &callback_ops[0];
-	status = htonl(NFS4ERR_OP_ILLEGAL);
-	goto out;
 }
 
 /*
-- 
1.6.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux