net: nfs: Consolidate handling of NFSv3 attributes

Instead of repeating the same large snippet for dealing with attributes
it should be shared with a helper function.

Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
Joe Hershberger 2016-08-15 15:03:22 -05:00
parent 347a901597
commit 051ed9af8c

111
net/nfs.c
View file

@ -588,47 +588,9 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
return 0; return 0;
} }
static int nfs_readlink_reply(uchar *pkt, unsigned len) static int nfs3_get_attributes_offset(uint32_t *data)
{ {
struct rpc_t rpc_pkt; if (ntohl(data[1]) != 0) {
int rlen;
debug("%s\n", __func__);
memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
return -NFS_RPC_ERR;
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
return -NFS_RPC_DROP;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
rpc_pkt.u.reply.data[0])
return -1;
if (supported_nfs_versions & NFSV2_FLAG) {
rlen = ntohl(rpc_pkt.u.reply.data[1]); /* new path length */
if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') {
int pathlen;
strcat(nfs_path, "/");
pathlen = strlen(nfs_path);
memcpy(nfs_path + pathlen,
(uchar *)&(rpc_pkt.u.reply.data[2]),
rlen);
nfs_path[pathlen + rlen] = 0;
} else {
memcpy(nfs_path,
(uchar *)&(rpc_pkt.u.reply.data[2]),
rlen);
nfs_path[rlen] = 0;
}
} else { /* NFSV3_FLAG */
int nfsv3_data_offset = 0;
if (ntohl(rpc_pkt.u.reply.data[1]) != 0) {
/* 'attributes_follow' flag is TRUE, /* 'attributes_follow' flag is TRUE,
* so we have attributes on 21 bytes */ * so we have attributes on 21 bytes */
/* Skip unused values : /* Skip unused values :
@ -646,11 +608,38 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
mtime; 64 bits value, mtime; 64 bits value,
ctime; 64 bits value, ctime; 64 bits value,
*/ */
nfsv3_data_offset = 22; return 22;
} else { } else {
/* 'attributes_follow' flag is FALSE, /* 'attributes_follow' flag is FALSE,
* so we don't have any attributes */ * so we don't have any attributes */
nfsv3_data_offset = 1; return 1;
}
}
static int nfs_readlink_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
int rlen;
int nfsv3_data_offset = 0;
debug("%s\n", __func__);
memcpy((unsigned char *)&rpc_pkt, pkt, len);
if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
return -NFS_RPC_ERR;
else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
return -NFS_RPC_DROP;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
rpc_pkt.u.reply.data[0])
return -1;
if (!(supported_nfs_versions & NFSV2_FLAG)) { /* NFSV3_FLAG */
nfsv3_data_offset =
nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
} }
/* new path length */ /* new path length */
@ -658,6 +647,7 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') { if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') {
int pathlen; int pathlen;
strcat(nfs_path, "/"); strcat(nfs_path, "/");
pathlen = strlen(nfs_path); pathlen = strlen(nfs_path);
memcpy(nfs_path + pathlen, memcpy(nfs_path + pathlen,
@ -670,7 +660,6 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
rlen); rlen);
nfs_path[rlen] = 0; nfs_path[rlen] = 0;
} }
}
return 0; return 0;
} }
@ -710,39 +699,17 @@ static int nfs_read_reply(uchar *pkt, unsigned len)
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 { /* NFSV3_FLAG */
if (ntohl(rpc_pkt.u.reply.data[1]) != 0) { int nfsv3_data_offset =
/* 'attributes_follow' is TRUE, nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
* so we have attributes on 21 bytes */
/* Skip unused values : /* count value */
type; 32 bits value, rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
mode; 32 bits value,
nlink; 32 bits value,
uid; 32 bits value,
gid; 32 bits value,
size; 64 bits value,
used; 64 bits value,
rdev; 64 bits value,
fsid; 64 bits value,
fileid; 64 bits value,
atime; 64 bits value,
mtime; 64 bits value,
ctime; 64 bits value,
*/
rlen = ntohl(rpc_pkt.u.reply.data[23]); /* count value */
/* Skip unused values : /* Skip unused values :
EOF: 32 bits value, EOF: 32 bits value,
data_size: 32 bits value, data_size: 32 bits value,
*/ */
data_ptr = (uchar *)&(rpc_pkt.u.reply.data[26]); data_ptr = (uchar *)
} else { &(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
/* attributes_follow is FALSE, so we don't have any attributes */
rlen = ntohl(rpc_pkt.u.reply.data[2]); /* count value */
/* Skip unused values :
EOF: 32 bits value,
data_size: 32 bits value,
*/
data_ptr = (uchar *)&(rpc_pkt.u.reply.data[5]);
}
} }
if (store_block(data_ptr, nfs_offset, rlen)) if (store_block(data_ptr, nfs_offset, rlen))