[PATCH v2 1/4] nfs: convert supported_nfs_versions bitfield to an enum

Christian Gmeiner christian.gmeiner at gmail.com
Fri Mar 10 10:51:52 CET 2023


From: Thomas RIENOESSL <thomas.rienoessl at bachmann.info>

Prep. work to support nfs v1.

Signed-off-by: Thomas RIENOESSL <thomas.rienoessl at bachmann.info>
---
 net/nfs.c | 93 +++++++++++++++++++++++++++++++------------------------
 1 file changed, 52 insertions(+), 41 deletions(-)

diff --git a/net/nfs.c b/net/nfs.c
index c6a124885e..d1858faaa9 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -76,10 +76,13 @@ static char *nfs_filename;
 static char *nfs_path;
 static char nfs_path_buff[2048];
 
-#define NFSV2_FLAG 1
-#define NFSV3_FLAG 1 << 1
-static char supported_nfs_versions = NFSV2_FLAG | NFSV3_FLAG;
+enum nfs_version {
+	NFS_UNKOWN = 0,
+	NFS_V2 = 2,
+	NFS_V3 = 3,
+};
 
+static enum nfs_version choosen_nfs_version = NFS_V3;
 static inline int store_block(uchar *src, unsigned offset, unsigned len)
 {
 	ulong newsize = offset + len;
@@ -188,10 +191,19 @@ static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
 	rpc_pkt.u.call.prog = htonl(rpc_prog);
 	switch (rpc_prog) {
 	case PROG_NFS:
-		if (supported_nfs_versions & NFSV2_FLAG)
-			rpc_pkt.u.call.vers = htonl(2);	/* NFS v2 */
-		else /* NFSV3_FLAG */
-			rpc_pkt.u.call.vers = htonl(3);	/* NFS v3 */
+		switch (choosen_nfs_version) {
+		case NFS_V2:
+			rpc_pkt.u.call.vers = htonl(2);
+			break;
+
+		case NFS_V3:
+			rpc_pkt.u.call.vers = htonl(3);
+			break;
+
+		case NFS_UNKOWN:
+			/* nothing to do */
+			break;
+		}
 		break;
 	case PROG_PORTMAP:
 	case PROG_MOUNT:
@@ -299,10 +311,10 @@ static void nfs_readlink_req(void)
 	p = &(data[0]);
 	p = rpc_add_credentials(p);
 
-	if (supported_nfs_versions & NFSV2_FLAG) {
+	if (choosen_nfs_version == NFS_V2) {
 		memcpy(p, filefh, NFS_FHSIZE);
 		p += (NFS_FHSIZE / 4);
-	} else { /* NFSV3_FLAG */
+	} else { /* NFS_V3 */
 		*p++ = htonl(filefh3_length);
 		memcpy(p, filefh, filefh3_length);
 		p += (filefh3_length / 4);
@@ -328,7 +340,7 @@ static void nfs_lookup_req(char *fname)
 	p = &(data[0]);
 	p = rpc_add_credentials(p);
 
-	if (supported_nfs_versions & NFSV2_FLAG) {
+	if (choosen_nfs_version == NFS_V2) {
 		memcpy(p, dirfh, NFS_FHSIZE);
 		p += (NFS_FHSIZE / 4);
 		*p++ = htonl(fnamelen);
@@ -340,7 +352,7 @@ static void nfs_lookup_req(char *fname)
 		len = (uint32_t *)p - (uint32_t *)&(data[0]);
 
 		rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
-	} else {  /* NFSV3_FLAG */
+	} else {  /* NFS_V3 */
 		*p++ = htonl(NFS_FHSIZE);	/* Dir handle length */
 		memcpy(p, dirfh, NFS_FHSIZE);
 		p += (NFS_FHSIZE / 4);
@@ -368,13 +380,13 @@ static void nfs_read_req(int offset, int readlen)
 	p = &(data[0]);
 	p = rpc_add_credentials(p);
 
-	if (supported_nfs_versions & NFSV2_FLAG) {
+	if (choosen_nfs_version == NFS_V2) {
 		memcpy(p, filefh, NFS_FHSIZE);
 		p += (NFS_FHSIZE / 4);
 		*p++ = htonl(offset);
 		*p++ = htonl(readlen);
 		*p++ = 0;
-	} else { /* NFSV3_FLAG */
+	} else { /* NFS_V3 */
 		*p++ = htonl(filefh3_length);
 		memcpy(p, filefh, filefh3_length);
 		p += (filefh3_length / 4);
@@ -398,15 +410,15 @@ static void nfs_send(void)
 
 	switch (nfs_state) {
 	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
-		if (supported_nfs_versions & NFSV2_FLAG)
+		if (choosen_nfs_version == NFS_V2)
 			rpc_lookup_req(PROG_MOUNT, 1);
-		else  /* NFSV3_FLAG */
+		else  /* NFS_V3 */
 			rpc_lookup_req(PROG_MOUNT, 3);
 		break;
 	case STATE_PRCLOOKUP_PROG_NFS_REQ:
-		if (supported_nfs_versions & NFSV2_FLAG)
+		if (choosen_nfs_version == NFS_V2)
 			rpc_lookup_req(PROG_NFS, 2);
-		else  /* NFSV3_FLAG */
+		else  /* NFS_V3 */
 			rpc_lookup_req(PROG_NFS, 3);
 		break;
 	case STATE_MOUNT_REQ:
@@ -531,31 +543,30 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
 		switch (ntohl(rpc_pkt.u.reply.astatus)) {
 		case NFS_RPC_SUCCESS: /* Not an error */
 			break;
-		case NFS_RPC_PROG_MISMATCH:
+		case NFS_RPC_PROG_MISMATCH: {
 			/* Remote can't support NFS version */
-			switch (ntohl(rpc_pkt.u.reply.data[0])) {
-			/* Minimal supported NFS version */
-			case 3:
-				debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d\n",
-				      (supported_nfs_versions & NFSV2_FLAG) ?
-						2 : 3,
-				      ntohl(rpc_pkt.u.reply.data[0]),
-				      ntohl(rpc_pkt.u.reply.data[1]));
-				debug("Will retry with NFSv3\n");
-				/* Clear NFSV2_FLAG from supported versions */
-				supported_nfs_versions &= ~NFSV2_FLAG;
-				return -NFS_RPC_PROG_MISMATCH;
-			case 4:
-			default:
+			const int min = ntohl(rpc_pkt.u.reply.data[0]);
+			const int max = ntohl(rpc_pkt.u.reply.data[1]);
+
+			if (max < NFS_V2 || max > NFS_V3 || min > NFS_V3) {
 				puts("*** ERROR: NFS version not supported");
 				debug(": Requested: V%d, accepted: min V%d - max V%d\n",
-				      (supported_nfs_versions & NFSV2_FLAG) ?
-						2 : 3,
+				      choosen_nfs_version,
 				      ntohl(rpc_pkt.u.reply.data[0]),
 				      ntohl(rpc_pkt.u.reply.data[1]));
 				puts("\n");
+				choosen_nfs_version = NFS_UNKOWN;
+				break;
 			}
-			break;
+
+			debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d\n",
+			      choosen_nfs_version,
+			      ntohl(rpc_pkt.u.reply.data[0]),
+			      ntohl(rpc_pkt.u.reply.data[1]));
+			debug("Will retry with NFSv%d\n", min);
+			choosen_nfs_version = min;
+			return -NFS_RPC_PROG_MISMATCH;
+		}
 		case NFS_RPC_PROG_UNAVAIL:
 		case NFS_RPC_PROC_UNAVAIL:
 		case NFS_RPC_GARBAGE_ARGS:
@@ -568,11 +579,11 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
 		return -1;
 	}
 
-	if (supported_nfs_versions & NFSV2_FLAG) {
+	if (choosen_nfs_version == NFS_V2) {
 		if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len)
 			return -NFS_RPC_DROP;
 		memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
-	} else {  /* NFSV3_FLAG */
+	} else {  /* NFS_V3 */
 		filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
 		if (filefh3_length > NFS3_FHSIZE)
 			filefh3_length  = NFS3_FHSIZE;
@@ -631,7 +642,7 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
 	    rpc_pkt.u.reply.data[0])
 		return -1;
 
-	if (!(supported_nfs_versions & NFSV2_FLAG)) { /* NFSV3_FLAG */
+	if (choosen_nfs_version == NFS_V3) {
 		nfsv3_data_offset =
 			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
 	}
@@ -692,10 +703,10 @@ static int nfs_read_reply(uchar *pkt, unsigned len)
 	if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10)))
 		putc('#');
 
-	if (supported_nfs_versions & NFSV2_FLAG) {
+	if (choosen_nfs_version == NFS_V2) {
 		rlen = ntohl(rpc_pkt.u.reply.data[18]);
 		data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]);
-	} else {  /* NFSV3_FLAG */
+	} else {  /* NFS_V3 */
 		int nfsv3_data_offset =
 			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
 
@@ -801,7 +812,7 @@ static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
 			nfs_state = STATE_UMOUNT_REQ;
 			nfs_send();
 		} else if (reply == -NFS_RPC_PROG_MISMATCH &&
-			   supported_nfs_versions != 0) {
+			   choosen_nfs_version != NFS_UNKOWN) {
 			/* umount */
 			nfs_state = STATE_UMOUNT_REQ;
 			nfs_send();
-- 
2.39.2



More information about the U-Boot mailing list