Check more carefully for failing requests. This improves the error message when trying to mount a non-exported nfs directory from: nfs_mount_req: file handle too big: 44831 to nfs_mount_req: Mounting gave error NFS3ERR_ACCES(0xd) . Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> --- fs/nfs.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/fs/nfs.c b/fs/nfs.c index 15ddab7915df..0be32322fb65 100644 --- a/fs/nfs.c +++ b/fs/nfs.c @@ -636,13 +636,33 @@ static uint32_t *nfs_read_post_op_attr(uint32_t *p, struct inode *inode) return p; } +static int nfserror_to_err(u32 nfserror, const char **errorname) +{ +#define E(NFSERR, ERR) \ + case NFSERR: \ + *errorname = #NFSERR; \ + return -ERR + + switch (nfserror) { + E(NFS3_OK, 0); + E(NFS3ERR_NOENT, ENOENT); + E(NFS3ERR_IO, EIO); + E(NFS3ERR_ACCES, EACCES); + E(NFS3ERR_NOTDIR, ENOTDIR); + E(NFS3ERR_NAMETOOLONG, ENAMETOOLONG); + + default: + *errorname = "???"; + return -EINVAL; + } +} /* * nfs_mount_req - Mount an NFS Filesystem */ static int nfs_mount_req(struct nfs_priv *npriv) { uint32_t data[1024]; - uint32_t *p; + uint32_t *p, status; int len; int pathlen; struct packet *nfs_packet; @@ -667,7 +687,21 @@ static int nfs_mount_req(struct nfs_priv *npriv) if (IS_ERR(nfs_packet)) return PTR_ERR(nfs_packet); - p = (void *)nfs_packet->data + sizeof(struct rpc_reply) + 4; + p = (void *)nfs_packet->data + sizeof(struct rpc_reply); + + /* + * Theoretically the error status is one of MNT3ERR_..., but the NFS + * constants are identical. + */ + status = ntoh32(net_read_uint32(p++)); + if (status != NFS3_OK) { + const char *error; + int ret; + + ret = nfserror_to_err(status, &error); + printf("%s: Mounting gave error %s(0x%x)\n", __func__, error, status); + return -ret; + } npriv->rootfh.size = ntoh32(net_read_uint32(p++)); if (npriv->rootfh.size > NFS3_FHSIZE) { @@ -719,7 +753,7 @@ static int nfs_lookup_req(struct nfs_priv *npriv, struct nfs_fh *fh, { struct nfs_inode *ninode = nfsi(inode); uint32_t data[1024]; - uint32_t *p; + uint32_t *p, status; int len; struct packet *nfs_packet; @@ -761,7 +795,16 @@ static int nfs_lookup_req(struct nfs_priv *npriv, struct nfs_fh *fh, if (IS_ERR(nfs_packet)) return PTR_ERR(nfs_packet); - p = (void *)nfs_packet->data + sizeof(struct rpc_reply) + 4; + p = (void *)nfs_packet->data + sizeof(struct rpc_reply); + status = ntoh32(net_read_uint32(p++)); + if (status != NFS3_OK) { + const char *error; + int ret; + + ret = nfserror_to_err(status, &error); + printf("%s: LOOKUP failed with error %s(0x%x)\n", __func__, error, status); + return ret; + } ninode->fh.size = ntoh32(net_read_uint32(p++)); if (ninode->fh.size > NFS3_FHSIZE) { @@ -787,7 +830,7 @@ static int nfs_lookup_req(struct nfs_priv *npriv, struct nfs_fh *fh, static void *nfs_readdirattr_req(struct nfs_priv *npriv, struct nfs_dir *dir) { uint32_t data[1024]; - uint32_t *p; + uint32_t *p, status; int len; struct packet *nfs_packet; void *buf; @@ -845,7 +888,17 @@ static void *nfs_readdirattr_req(struct nfs_priv *npriv, struct nfs_dir *dir) if (IS_ERR(nfs_packet)) return NULL; - p = (void *)nfs_packet->data + sizeof(struct rpc_reply) + 4; + p = (void *)nfs_packet->data + sizeof(struct rpc_reply); + status = ntoh32(net_read_uint32(p++)); + if (status != NFS3_OK) { + const char *error; + int ret; + + ret = nfserror_to_err(status, &error); + printf("%s: READDIR failed with error %s(%u)\n", __func__, error, status); + return NULL; + } + p = nfs_read_post_op_attr(p, NULL); /* update cookieverf */ @@ -879,7 +932,7 @@ static int nfs_read_req(struct file_priv *priv, uint64_t offset, uint32_t readlen) { uint32_t data[1024]; - uint32_t *p; + uint32_t *p, status; int len; struct packet *nfs_packet; uint32_t rlen, eof; @@ -922,7 +975,16 @@ static int nfs_read_req(struct file_priv *priv, uint64_t offset, if (IS_ERR(nfs_packet)) return PTR_ERR(nfs_packet); - p = (void *)nfs_packet->data + sizeof(struct rpc_reply) + 4; + p = (void *)nfs_packet->data + sizeof(struct rpc_reply); + status = ntoh32(net_read_uint32(p++)); + if (status != NFS3_OK) { + const char *error; + int ret; + + ret = nfserror_to_err(status, &error); + printf("%s: READ failed with error %s(0x%x)\n", __func__, error, status); + return ret; + } p = nfs_read_post_op_attr(p, NULL); @@ -981,7 +1043,7 @@ static int nfs_readlink_req(struct nfs_priv *npriv, struct nfs_fh *fh, char **target) { uint32_t data[1024]; - uint32_t *p; + uint32_t *p, status; uint32_t len; struct packet *nfs_packet; @@ -1017,7 +1079,16 @@ static int nfs_readlink_req(struct nfs_priv *npriv, struct nfs_fh *fh, if (IS_ERR(nfs_packet)) return PTR_ERR(nfs_packet); - p = (void *)nfs_packet->data + sizeof(struct rpc_reply) + 4; + p = (void *)nfs_packet->data + sizeof(struct rpc_reply); + status = ntoh32(net_read_uint32(p++)); + if (status != NFS3_OK) { + const char *error; + int ret; + + ret = nfserror_to_err(status, &error); + printf("%s: READLINK failed with error %s(0x%x)\n", __func__, error, status); + return ret; + } p = nfs_read_post_op_attr(p, NULL); -- 2.28.0 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox