nfs: convert supported_nfs_versions bitfield to an enum

Prep. work to support nfs v1.

Signed-off-by: Thomas RIENOESSL <thomas.rienoessl@bachmann.info>
This commit is contained in:
Thomas RIENOESSL 2023-03-10 10:51:52 +01:00 committed by Tom Rini
parent 96d58ecac8
commit 948d7a6022

View file

@ -76,10 +76,13 @@ static char *nfs_filename;
static char *nfs_path; static char *nfs_path;
static char nfs_path_buff[2048]; static char nfs_path_buff[2048];
#define NFSV2_FLAG 1 enum nfs_version {
#define NFSV3_FLAG 1 << 1 NFS_UNKOWN = 0,
static char supported_nfs_versions = NFSV2_FLAG | NFSV3_FLAG; 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) static inline int store_block(uchar *src, unsigned offset, unsigned len)
{ {
ulong newsize = offset + 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); rpc_pkt.u.call.prog = htonl(rpc_prog);
switch (rpc_prog) { switch (rpc_prog) {
case PROG_NFS: case PROG_NFS:
if (supported_nfs_versions & NFSV2_FLAG) switch (choosen_nfs_version) {
rpc_pkt.u.call.vers = htonl(2); /* NFS v2 */ case NFS_V2:
else /* NFSV3_FLAG */ rpc_pkt.u.call.vers = htonl(2);
rpc_pkt.u.call.vers = htonl(3); /* NFS v3 */ break;
case NFS_V3:
rpc_pkt.u.call.vers = htonl(3);
break;
case NFS_UNKOWN:
/* nothing to do */
break;
}
break; break;
case PROG_PORTMAP: case PROG_PORTMAP:
case PROG_MOUNT: case PROG_MOUNT:
@ -299,10 +311,10 @@ static void nfs_readlink_req(void)
p = &(data[0]); p = &(data[0]);
p = rpc_add_credentials(p); p = rpc_add_credentials(p);
if (supported_nfs_versions & NFSV2_FLAG) { if (choosen_nfs_version == NFS_V2) {
memcpy(p, filefh, NFS_FHSIZE); memcpy(p, filefh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4); p += (NFS_FHSIZE / 4);
} else { /* NFSV3_FLAG */ } else { /* NFS_V3 */
*p++ = htonl(filefh3_length); *p++ = htonl(filefh3_length);
memcpy(p, filefh, filefh3_length); memcpy(p, filefh, filefh3_length);
p += (filefh3_length / 4); p += (filefh3_length / 4);
@ -328,7 +340,7 @@ static void nfs_lookup_req(char *fname)
p = &(data[0]); p = &(data[0]);
p = rpc_add_credentials(p); p = rpc_add_credentials(p);
if (supported_nfs_versions & NFSV2_FLAG) { if (choosen_nfs_version == NFS_V2) {
memcpy(p, dirfh, NFS_FHSIZE); memcpy(p, dirfh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4); p += (NFS_FHSIZE / 4);
*p++ = htonl(fnamelen); *p++ = htonl(fnamelen);
@ -340,7 +352,7 @@ static void nfs_lookup_req(char *fname)
len = (uint32_t *)p - (uint32_t *)&(data[0]); len = (uint32_t *)p - (uint32_t *)&(data[0]);
rpc_req(PROG_NFS, NFS_LOOKUP, data, len); rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
} else { /* NFSV3_FLAG */ } else { /* NFS_V3 */
*p++ = htonl(NFS_FHSIZE); /* Dir handle length */ *p++ = htonl(NFS_FHSIZE); /* Dir handle length */
memcpy(p, dirfh, NFS_FHSIZE); memcpy(p, dirfh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4); p += (NFS_FHSIZE / 4);
@ -368,13 +380,13 @@ static void nfs_read_req(int offset, int readlen)
p = &(data[0]); p = &(data[0]);
p = rpc_add_credentials(p); p = rpc_add_credentials(p);
if (supported_nfs_versions & NFSV2_FLAG) { if (choosen_nfs_version == NFS_V2) {
memcpy(p, filefh, NFS_FHSIZE); memcpy(p, filefh, NFS_FHSIZE);
p += (NFS_FHSIZE / 4); p += (NFS_FHSIZE / 4);
*p++ = htonl(offset); *p++ = htonl(offset);
*p++ = htonl(readlen); *p++ = htonl(readlen);
*p++ = 0; *p++ = 0;
} else { /* NFSV3_FLAG */ } else { /* NFS_V3 */
*p++ = htonl(filefh3_length); *p++ = htonl(filefh3_length);
memcpy(p, filefh, filefh3_length); memcpy(p, filefh, filefh3_length);
p += (filefh3_length / 4); p += (filefh3_length / 4);
@ -398,15 +410,15 @@ static void nfs_send(void)
switch (nfs_state) { switch (nfs_state) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ: case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
if (supported_nfs_versions & NFSV2_FLAG) if (choosen_nfs_version == NFS_V2)
rpc_lookup_req(PROG_MOUNT, 1); rpc_lookup_req(PROG_MOUNT, 1);
else /* NFSV3_FLAG */ else /* NFS_V3 */
rpc_lookup_req(PROG_MOUNT, 3); rpc_lookup_req(PROG_MOUNT, 3);
break; break;
case STATE_PRCLOOKUP_PROG_NFS_REQ: case STATE_PRCLOOKUP_PROG_NFS_REQ:
if (supported_nfs_versions & NFSV2_FLAG) if (choosen_nfs_version == NFS_V2)
rpc_lookup_req(PROG_NFS, 2); rpc_lookup_req(PROG_NFS, 2);
else /* NFSV3_FLAG */ else /* NFS_V3 */
rpc_lookup_req(PROG_NFS, 3); rpc_lookup_req(PROG_NFS, 3);
break; break;
case STATE_MOUNT_REQ: case STATE_MOUNT_REQ:
@ -531,31 +543,30 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
switch (ntohl(rpc_pkt.u.reply.astatus)) { switch (ntohl(rpc_pkt.u.reply.astatus)) {
case NFS_RPC_SUCCESS: /* Not an error */ case NFS_RPC_SUCCESS: /* Not an error */
break; break;
case NFS_RPC_PROG_MISMATCH: case NFS_RPC_PROG_MISMATCH: {
/* Remote can't support NFS version */ /* Remote can't support NFS version */
switch (ntohl(rpc_pkt.u.reply.data[0])) { const int min = ntohl(rpc_pkt.u.reply.data[0]);
/* Minimal supported NFS version */ const int max = ntohl(rpc_pkt.u.reply.data[1]);
case 3:
debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d\n", if (max < NFS_V2 || max > NFS_V3 || min > NFS_V3) {
(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:
puts("*** ERROR: NFS version not supported"); puts("*** ERROR: NFS version not supported");
debug(": Requested: V%d, accepted: min V%d - max V%d\n", debug(": Requested: V%d, accepted: min V%d - max V%d\n",
(supported_nfs_versions & NFSV2_FLAG) ? choosen_nfs_version,
2 : 3,
ntohl(rpc_pkt.u.reply.data[0]), ntohl(rpc_pkt.u.reply.data[0]),
ntohl(rpc_pkt.u.reply.data[1])); ntohl(rpc_pkt.u.reply.data[1]));
puts("\n"); 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_PROG_UNAVAIL:
case NFS_RPC_PROC_UNAVAIL: case NFS_RPC_PROC_UNAVAIL:
case NFS_RPC_GARBAGE_ARGS: case NFS_RPC_GARBAGE_ARGS:
@ -568,11 +579,11 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
return -1; 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) if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len)
return -NFS_RPC_DROP; return -NFS_RPC_DROP;
memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); 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]); filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
if (filefh3_length > NFS3_FHSIZE) if (filefh3_length > NFS3_FHSIZE)
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]) rpc_pkt.u.reply.data[0])
return -1; return -1;
if (!(supported_nfs_versions & NFSV2_FLAG)) { /* NFSV3_FLAG */ if (choosen_nfs_version == NFS_V3) {
nfsv3_data_offset = nfsv3_data_offset =
nfs3_get_attributes_offset(rpc_pkt.u.reply.data); 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))) if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10)))
putc('#'); putc('#');
if (supported_nfs_versions & NFSV2_FLAG) { if (choosen_nfs_version == NFS_V2) {
rlen = ntohl(rpc_pkt.u.reply.data[18]); rlen = ntohl(rpc_pkt.u.reply.data[18]);
data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]); data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]);
} else { /* NFSV3_FLAG */ } else { /* NFS_V3 */
int nfsv3_data_offset = int nfsv3_data_offset =
nfs3_get_attributes_offset(rpc_pkt.u.reply.data); 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_state = STATE_UMOUNT_REQ;
nfs_send(); nfs_send();
} else if (reply == -NFS_RPC_PROG_MISMATCH && } else if (reply == -NFS_RPC_PROG_MISMATCH &&
supported_nfs_versions != 0) { choosen_nfs_version != NFS_UNKOWN) {
/* umount */ /* umount */
nfs_state = STATE_UMOUNT_REQ; nfs_state = STATE_UMOUNT_REQ;
nfs_send(); nfs_send();