forked from Imagelibrary/rtems
nfsclient: Add and use nfsEvaluateStatus()
The NFS status codes do not map directly to the corresponding errno values.
This commit is contained in:
@@ -703,6 +703,95 @@ static RpcUdpXactPool bigPool = 0;
|
||||
Implementation
|
||||
*****************************************/
|
||||
|
||||
static int nfsEvaluateStatus(nfsstat nfsStatus)
|
||||
{
|
||||
static const uint8_t nfsStatusToErrno [71] = {
|
||||
[NFS_OK] = 0,
|
||||
[NFSERR_PERM] = EPERM,
|
||||
[NFSERR_NOENT] = ENOENT,
|
||||
[3] = EIO,
|
||||
[4] = EIO,
|
||||
[NFSERR_IO] = EIO,
|
||||
[NFSERR_NXIO] = ENXIO,
|
||||
[7] = EIO,
|
||||
[8] = EIO,
|
||||
[9] = EIO,
|
||||
[10] = EIO,
|
||||
[11] = EIO,
|
||||
[12] = EIO,
|
||||
[NFSERR_ACCES] = EACCES,
|
||||
[14] = EIO,
|
||||
[15] = EIO,
|
||||
[16] = EIO,
|
||||
[NFSERR_EXIST] = EEXIST,
|
||||
[18] = EIO,
|
||||
[NFSERR_NODEV] = ENODEV,
|
||||
[NFSERR_NOTDIR] = ENOTDIR,
|
||||
[NFSERR_ISDIR] = EISDIR,
|
||||
[22] = EIO,
|
||||
[24] = EIO,
|
||||
[25] = EIO,
|
||||
[26] = EIO,
|
||||
[27] = EIO,
|
||||
[NFSERR_FBIG] = EFBIG,
|
||||
[NFSERR_NOSPC] = ENOSPC,
|
||||
[29] = EIO,
|
||||
[NFSERR_ROFS] = EROFS,
|
||||
[31] = EIO,
|
||||
[32] = EIO,
|
||||
[34] = EIO,
|
||||
[35] = EIO,
|
||||
[36] = EIO,
|
||||
[37] = EIO,
|
||||
[38] = EIO,
|
||||
[39] = EIO,
|
||||
[40] = EIO,
|
||||
[41] = EIO,
|
||||
[42] = EIO,
|
||||
[44] = EIO,
|
||||
[45] = EIO,
|
||||
[46] = EIO,
|
||||
[47] = EIO,
|
||||
[48] = EIO,
|
||||
[49] = EIO,
|
||||
[50] = EIO,
|
||||
[51] = EIO,
|
||||
[52] = EIO,
|
||||
[54] = EIO,
|
||||
[55] = EIO,
|
||||
[56] = EIO,
|
||||
[57] = EIO,
|
||||
[58] = EIO,
|
||||
[59] = EIO,
|
||||
[60] = EIO,
|
||||
[61] = EIO,
|
||||
[62] = EIO,
|
||||
[NFSERR_NAMETOOLONG] = ENAMETOOLONG,
|
||||
[64] = EIO,
|
||||
[65] = EIO,
|
||||
[NFSERR_NOTEMPTY] = ENOTEMPTY,
|
||||
[67] = EIO,
|
||||
[68] = EIO,
|
||||
[NFSERR_DQUOT] = EDQUOT,
|
||||
[NFSERR_STALE] = ESTALE
|
||||
};
|
||||
|
||||
size_t idx = (size_t) nfsStatus;
|
||||
int eno = EIO;
|
||||
int rv = 0;
|
||||
|
||||
if (idx < sizeof(nfsStatusToErrno) / sizeof(nfsStatusToErrno [0])) {
|
||||
eno = nfsStatusToErrno [idx];
|
||||
}
|
||||
|
||||
if (eno != 0) {
|
||||
errno = eno;
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Create a Nfs object. This is
|
||||
* per-mounted NFS information.
|
||||
*
|
||||
@@ -1126,27 +1215,30 @@ int rval = -1;
|
||||
static int
|
||||
updateAttr(NfsNode node, int force)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (force
|
||||
#ifdef CONFIG_ATTR_LIFETIME
|
||||
|| (nowSeconds() - node->age > CONFIG_ATTR_LIFETIME)
|
||||
#endif
|
||||
) {
|
||||
if ( nfscall(node->nfs->server,
|
||||
NFSPROC_GETATTR,
|
||||
(xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_attrstat, &node->serporid) )
|
||||
return -1;
|
||||
) {
|
||||
rv = nfscall(
|
||||
node->nfs->server,
|
||||
NFSPROC_GETATTR,
|
||||
(xdrproc_t) xdr_nfs_fh, &SERP_FILE(node),
|
||||
(xdrproc_t) xdr_attrstat, &node->serporid
|
||||
);
|
||||
|
||||
if ( NFS_OK != node->serporid.status ) {
|
||||
errno = node->serporid.status;
|
||||
return -1;
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(node->serporid.status);
|
||||
|
||||
if (rv == 0) {
|
||||
node->age = nowSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
node->age = nowSeconds();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1528,16 +1620,20 @@ char *dupname;
|
||||
|
||||
SERP_ARGS(tNode).linkarg.to.name = dupname;
|
||||
|
||||
if ( nfscall(tNode->nfs->server,
|
||||
NFSPROC_LINK,
|
||||
(xdrproc_t)xdr_linkargs, &SERP_FILE(tNode),
|
||||
(xdrproc_t)xdr_nfsstat, &status)
|
||||
|| (NFS_OK != (errno = status))
|
||||
) {
|
||||
rv = nfscall(
|
||||
tNode->nfs->server,
|
||||
NFSPROC_LINK,
|
||||
(xdrproc_t)xdr_linkargs, &SERP_FILE(tNode),
|
||||
(xdrproc_t)xdr_nfsstat, &status
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(status);
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
perror("nfs_link");
|
||||
if (rv != 0) {
|
||||
perror("nfs_link");
|
||||
}
|
||||
#endif
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
free(dupname);
|
||||
@@ -1552,6 +1648,7 @@ static int nfs_do_unlink(
|
||||
int proc
|
||||
)
|
||||
{
|
||||
int rv = 0;
|
||||
nfsstat status;
|
||||
NfsNode node = loc->node_access;
|
||||
Nfs nfs = node->nfs;
|
||||
@@ -1571,19 +1668,23 @@ char *name = NFSPROC_REMOVE == proc ?
|
||||
fprintf(stderr,"%s '%s'\n", name, node->args.name);
|
||||
#endif
|
||||
|
||||
if ( nfscall(nfs->server,
|
||||
proc,
|
||||
(xdrproc_t)xdr_diropargs, &node->args,
|
||||
(xdrproc_t)xdr_nfsstat, &status)
|
||||
|| (NFS_OK != (errno = status))
|
||||
) {
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
proc,
|
||||
(xdrproc_t)xdr_diropargs, &node->args,
|
||||
(xdrproc_t)xdr_nfsstat, &status
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(status);
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
perror(name);
|
||||
if (rv != 0) {
|
||||
perror(name);
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int nfs_chown(
|
||||
@@ -1926,15 +2027,20 @@ char *dupname;
|
||||
SERP_ARGS(node).createarg.attributes.mtime.seconds = now.tv_sec;
|
||||
SERP_ARGS(node).createarg.attributes.mtime.useconds = now.tv_usec;
|
||||
|
||||
if ( nfscall( nfs->server,
|
||||
(type == S_IFDIR) ? NFSPROC_MKDIR : NFSPROC_CREATE,
|
||||
(xdrproc_t)xdr_createargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_diropres, &res)
|
||||
|| (NFS_OK != (errno = res.status)) ) {
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
(type == S_IFDIR) ? NFSPROC_MKDIR : NFSPROC_CREATE,
|
||||
(xdrproc_t)xdr_createargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_diropres, &res
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(res.status);
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
perror("nfs_mknod");
|
||||
if (rv != 0) {
|
||||
perror("nfs_mknod");
|
||||
}
|
||||
#endif
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
free(dupname);
|
||||
@@ -2017,15 +2123,18 @@ char *dupname;
|
||||
SERP_ARGS(node).symlinkarg.attributes.mtime.seconds = now.tv_sec;
|
||||
SERP_ARGS(node).symlinkarg.attributes.mtime.useconds = now.tv_usec;
|
||||
|
||||
if ( nfscall( nfs->server,
|
||||
NFSPROC_SYMLINK,
|
||||
(xdrproc_t)xdr_symlinkargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_nfsstat, &status)
|
||||
|| (NFS_OK != (errno = status)) ) {
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
NFSPROC_SYMLINK,
|
||||
(xdrproc_t)xdr_symlinkargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_nfsstat, &status
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(status);
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
perror("nfs_symlink");
|
||||
#endif
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
free(dupname);
|
||||
@@ -2039,24 +2148,33 @@ static ssize_t nfs_readlink_with_node(
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
ssize_t rv;
|
||||
Nfs nfs = node->nfs;
|
||||
readlinkres_strbuf rr;
|
||||
|
||||
rr.strbuf.buf = buf;
|
||||
rr.strbuf.max = len - 1;
|
||||
|
||||
if ( nfscall(nfs->server,
|
||||
NFSPROC_READLINK,
|
||||
(xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_readlinkres_strbuf, &rr)
|
||||
|| (NFS_OK != (errno = rr.status)) ) {
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
NFSPROC_READLINK,
|
||||
(xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_readlinkres_strbuf, &rr
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(rr.status);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = (ssize_t) strlen(rr.strbuf.buf);
|
||||
} else {
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
perror("nfs_readlink_with_node");
|
||||
perror("nfs_readlink_with_node");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return (ssize_t) strlen(rr.strbuf.buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static ssize_t nfs_readlink(
|
||||
@@ -2102,8 +2220,9 @@ static int nfs_rename(
|
||||
(xdrproc_t) xdr_nfsstat,
|
||||
&status
|
||||
);
|
||||
if (rv == 0 && (errno = status) != NFS_OK) {
|
||||
rv = -1;
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(status);
|
||||
}
|
||||
|
||||
free(dupname);
|
||||
@@ -2277,6 +2396,7 @@ static ssize_t nfs_file_read_chunk(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
ssize_t rv;
|
||||
readres rr;
|
||||
Nfs nfs = node->nfs;
|
||||
|
||||
@@ -2286,29 +2406,31 @@ Nfs nfs = node->nfs;
|
||||
|
||||
rr.readres_u.reply.data.data_val = buffer;
|
||||
|
||||
if ( nfscall( nfs->server,
|
||||
NFSPROC_READ,
|
||||
(xdrproc_t)xdr_readargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_readres, &rr) ) {
|
||||
return -1;
|
||||
}
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
NFSPROC_READ,
|
||||
(xdrproc_t)xdr_readargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_readres, &rr
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(rr.status);
|
||||
|
||||
if (NFS_OK != rr.status) {
|
||||
rtems_set_errno_and_return_minus_one(rr.status);
|
||||
}
|
||||
if (rv == 0) {
|
||||
rv = rr.readres_u.reply.data.data_len;
|
||||
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
fprintf(stderr,
|
||||
"Read %i (asked for %i) bytes from offset %i to 0x%08x\n",
|
||||
rr.readres_u.reply.data.data_len,
|
||||
count,
|
||||
iop->offset,
|
||||
rr.readres_u.reply.data.data_val);
|
||||
fprintf(stderr,
|
||||
"Read %i (asked for %i) bytes from offset %i to 0x%08x\n",
|
||||
rr.readres_u.reply.data.data_len,
|
||||
count,
|
||||
iop->offset,
|
||||
rr.readres_u.reply.data.data_val);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return rr.readres_u.reply.data.data_len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static ssize_t nfs_file_read(
|
||||
@@ -2353,6 +2475,7 @@ static ssize_t nfs_dir_read(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
ssize_t rv;
|
||||
DirInfo di = iop->pathinfo.node_access_2;
|
||||
RpcUdpServer server = ((Nfs)iop->pathinfo.mt_entry->fs_info)->server;
|
||||
|
||||
@@ -2388,20 +2511,22 @@ RpcUdpServer server = ((Nfs)iop->pathinfo.mt_entry->fs_info)->server;
|
||||
count, di->len);
|
||||
#endif
|
||||
|
||||
if ( nfscall(
|
||||
server,
|
||||
NFSPROC_READDIR,
|
||||
(xdrproc_t)xdr_readdirargs, &di->readdirargs,
|
||||
(xdrproc_t)xdr_dir_info, di) ) {
|
||||
return -1;
|
||||
rv = nfscall(
|
||||
server,
|
||||
NFSPROC_READDIR,
|
||||
(xdrproc_t)xdr_readdirargs, &di->readdirargs,
|
||||
(xdrproc_t)xdr_dir_info, di
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(di->status);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = (char*)di->ptr - (char*)buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NFS_OK != di->status) {
|
||||
rtems_set_errno_and_return_minus_one(di->status);
|
||||
}
|
||||
|
||||
return (char*)di->ptr - (char*)buffer;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static ssize_t nfs_file_write(
|
||||
@@ -2410,9 +2535,9 @@ static ssize_t nfs_file_write(
|
||||
size_t count
|
||||
)
|
||||
{
|
||||
ssize_t rv;
|
||||
NfsNode node = iop->pathinfo.node_access;
|
||||
Nfs nfs = node->nfs;
|
||||
int e;
|
||||
|
||||
if (count > NFS_MAXDATA)
|
||||
count = NFS_MAXDATA;
|
||||
@@ -2435,25 +2560,28 @@ int e;
|
||||
* on the PROC specifier
|
||||
*/
|
||||
|
||||
if ( nfscall( nfs->server,
|
||||
NFSPROC_WRITE,
|
||||
(xdrproc_t)xdr_writeargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_attrstat, &node->serporid) ) {
|
||||
return -1;
|
||||
rv = nfscall(
|
||||
nfs->server,
|
||||
NFSPROC_WRITE,
|
||||
(xdrproc_t)xdr_writeargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_attrstat, &node->serporid
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(node->serporid.status);
|
||||
|
||||
if (rv == 0) {
|
||||
node->age = nowSeconds();
|
||||
|
||||
iop->offset += count;
|
||||
rv = count;
|
||||
} else {
|
||||
/* try at least to recover the current attributes */
|
||||
updateAttr(node, 1 /* force */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NFS_OK != (e=node->serporid.status) ) {
|
||||
/* try at least to recover the current attributes */
|
||||
updateAttr(node, 1 /* force */);
|
||||
rtems_set_errno_and_return_minus_one(e);
|
||||
}
|
||||
|
||||
node->age = nowSeconds();
|
||||
|
||||
iop->offset += count;
|
||||
|
||||
return count;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static off_t nfs_dir_lseek(
|
||||
@@ -2590,10 +2718,9 @@ fattr *fa = &SERP_ATTR(node);
|
||||
static int
|
||||
nfs_sattr(NfsNode node, sattr *arg, u_long mask)
|
||||
{
|
||||
|
||||
int rv;
|
||||
struct timeval now;
|
||||
nfstime nfsnow, t;
|
||||
int e;
|
||||
u_int mode;
|
||||
|
||||
if (updateAttr(node, 0 /* only if old */))
|
||||
@@ -2642,31 +2769,35 @@ u_int mode;
|
||||
|
||||
node->serporid.status = NFS_OK;
|
||||
|
||||
if ( nfscall( node->nfs->server,
|
||||
NFSPROC_SETATTR,
|
||||
(xdrproc_t)xdr_sattrargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_attrstat, &node->serporid) ) {
|
||||
rv = nfscall(
|
||||
node->nfs->server,
|
||||
NFSPROC_SETATTR,
|
||||
(xdrproc_t)xdr_sattrargs, &SERP_FILE(node),
|
||||
(xdrproc_t)xdr_attrstat, &node->serporid
|
||||
);
|
||||
|
||||
if (rv == 0) {
|
||||
rv = nfsEvaluateStatus(node->serporid.status);
|
||||
|
||||
if (rv == 0) {
|
||||
node->age = nowSeconds();
|
||||
} else {
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
fprintf(stderr,"nfs_sattr: %s\n",strerror(errno));
|
||||
#endif
|
||||
/* try at least to recover the current attributes */
|
||||
updateAttr(node, 1 /* force */);
|
||||
}
|
||||
} else {
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
fprintf(stderr,
|
||||
"nfs_sattr (mask 0x%08x): %s",
|
||||
mask,
|
||||
strerror(errno));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NFS_OK != (e=node->serporid.status) ) {
|
||||
#if DEBUG & DEBUG_SYSCALLS
|
||||
fprintf(stderr,"nfs_sattr: %s\n",strerror(e));
|
||||
#endif
|
||||
/* try at least to recover the current attributes */
|
||||
updateAttr(node, 1 /* force */);
|
||||
rtems_set_errno_and_return_minus_one(e);
|
||||
}
|
||||
|
||||
node->age = nowSeconds();
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* just set the size attribute to 'length'
|
||||
|
||||
Reference in New Issue
Block a user