diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-10-02 11:30:33 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-10-02 15:27:35 +0200 |
commit | c69ef3b6a52f3d3973b6ae9b2c280f8c86c64eec (patch) | |
tree | 5ff7db18514dfda1d14f00756e789c65e6222155 /cpukit/libfs/src/nfsclient/src/nfs.c | |
parent | nfsclient: Fix for short enums (diff) | |
download | rtems-c69ef3b6a52f3d3973b6ae9b2c280f8c86c64eec.tar.bz2 |
nfsclient: Add and use nfsEvaluateStatus()
The NFS status codes do not map directly to the corresponding errno
values.
Diffstat (limited to 'cpukit/libfs/src/nfsclient/src/nfs.c')
-rw-r--r-- | cpukit/libfs/src/nfsclient/src/nfs.c | 359 |
1 files changed, 245 insertions, 114 deletions
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c index 97d1ba55c8..2627726dc0 100644 --- a/cpukit/libfs/src/nfsclient/src/nfs.c +++ b/cpukit/libfs/src/nfsclient/src/nfs.c @@ -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); - node->age = nowSeconds(); + if (rv == 0) { + 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 (NFS_OK != di->status) { - rtems_set_errno_and_return_minus_one(di->status); + if (rv == 0) { + rv = (char*)di->ptr - (char*)buffer; + } } - 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 (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); - } + if (rv == 0) { + rv = nfsEvaluateStatus(node->serporid.status); - node->age = nowSeconds(); + if (rv == 0) { + node->age = nowSeconds(); - iop->offset += count; + iop->offset += count; + rv = count; + } else { + /* try at least to recover the current attributes */ + updateAttr(node, 1 /* force */); + } + } - 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' |