Commit 2d5e9ebc authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Don't translate those NFSv4 errors that are needed by

the kernel itself into EIO.

Fix a signed/unsigned bug in nfs4_increment_seqid.
parent 88e4b0f2
...@@ -376,9 +376,9 @@ nfs4_put_open_state(struct nfs4_state *state) ...@@ -376,9 +376,9 @@ nfs4_put_open_state(struct nfs4_state *state)
* see comments nfs_fs.h:seqid_mutating_error() * see comments nfs_fs.h:seqid_mutating_error()
*/ */
void void
nfs4_increment_seqid(u32 status, struct nfs4_state_owner *sp) nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
{ {
if (status == NFS_OK || seqid_mutating_err(status)) if (status == NFS_OK || seqid_mutating_err(-status))
sp->so_seqid++; sp->so_seqid++;
} }
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
/* Mapping from NFS error code to "errno" error code. */ /* Mapping from NFS error code to "errno" error code. */
#define errno_NFSERR_IO EIO #define errno_NFSERR_IO EIO
extern int nfs_stat_to_errno(int); static int nfs_stat_to_errno(int);
/* NFSv4 COMPOUND tags are only wanted for debugging purposes */ /* NFSv4 COMPOUND tags are only wanted for debugging purposes */
#ifdef DEBUG #ifdef DEBUG
...@@ -2650,6 +2650,67 @@ nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) ...@@ -2650,6 +2650,67 @@ nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
return p; return p;
} }
/*
* We need to translate between nfs status return values and
* the local errno values which may not be the same.
*/
static struct {
int stat;
int errno;
} nfs_errtbl[] = {
{ NFS4_OK, 0 },
{ NFS4ERR_PERM, EPERM },
{ NFS4ERR_NOENT, ENOENT },
{ NFS4ERR_IO, errno_NFSERR_IO },
{ NFS4ERR_NXIO, ENXIO },
{ NFS4ERR_ACCESS, EACCES },
{ NFS4ERR_EXIST, EEXIST },
{ NFS4ERR_XDEV, EXDEV },
{ NFS4ERR_NOTDIR, ENOTDIR },
{ NFS4ERR_ISDIR, EISDIR },
{ NFS4ERR_INVAL, EINVAL },
{ NFS4ERR_FBIG, EFBIG },
{ NFS4ERR_NOSPC, ENOSPC },
{ NFS4ERR_ROFS, EROFS },
{ NFS4ERR_MLINK, EMLINK },
{ NFS4ERR_NAMETOOLONG, ENAMETOOLONG },
{ NFS4ERR_NOTEMPTY, ENOTEMPTY },
{ NFS4ERR_DQUOT, EDQUOT },
{ NFS4ERR_STALE, ESTALE },
{ NFS4ERR_BADHANDLE, EBADHANDLE },
{ NFS4ERR_BAD_COOKIE, EBADCOOKIE },
{ NFS4ERR_NOTSUPP, ENOTSUPP },
{ NFS4ERR_TOOSMALL, ETOOSMALL },
{ NFS4ERR_SERVERFAULT, ESERVERFAULT },
{ NFS4ERR_BADTYPE, EBADTYPE },
{ NFS4ERR_LOCKED, EAGAIN },
{ NFS4ERR_RESOURCE, EREMOTEIO },
{ NFS4ERR_SYMLINK, ELOOP },
{ NFS4ERR_OP_ILLEGAL, EOPNOTSUPP },
{ NFS4ERR_DEADLOCK, EDEADLK },
{ -1, EIO }
};
/*
* Convert an NFS error code to a local one.
* This one is used jointly by NFSv2 and NFSv3.
*/
static int
nfs_stat_to_errno(int stat)
{
int i;
for (i = 0; nfs_errtbl[i].stat != -1; i++) {
if (nfs_errtbl[i].stat == stat)
return nfs_errtbl[i].errno;
}
/* If we cannot translate the error, the recovery routines should
* handle it.
* Note: remaining NFSv4 error codes have values > 10000, so should
* not conflict with native Linux error codes.
*/
return stat;
}
#ifndef MAX #ifndef MAX
# define MAX(a, b) (((a) > (b))? (a) : (b)) # define MAX(a, b) (((a) > (b))? (a) : (b))
#endif #endif
......
...@@ -88,6 +88,76 @@ enum nfs_opnum4 { ...@@ -88,6 +88,76 @@ enum nfs_opnum4 {
OP_WRITE = 38, OP_WRITE = 38,
}; };
enum nfsstat4 {
NFS4_OK = 0,
NFS4ERR_PERM = 1,
NFS4ERR_NOENT = 2,
NFS4ERR_IO = 5,
NFS4ERR_NXIO = 6,
NFS4ERR_ACCESS = 13,
NFS4ERR_EXIST = 17,
NFS4ERR_XDEV = 18,
/* Unused/reserved 19 */
NFS4ERR_NOTDIR = 20,
NFS4ERR_ISDIR = 21,
NFS4ERR_INVAL = 22,
NFS4ERR_FBIG = 27,
NFS4ERR_NOSPC = 28,
NFS4ERR_ROFS = 30,
NFS4ERR_MLINK = 31,
NFS4ERR_NAMETOOLONG = 63,
NFS4ERR_NOTEMPTY = 66,
NFS4ERR_DQUOT = 69,
NFS4ERR_STALE = 70,
NFS4ERR_BADHANDLE = 10001,
NFS4ERR_BAD_COOKIE = 10003,
NFS4ERR_NOTSUPP = 10004,
NFS4ERR_TOOSMALL = 10005,
NFS4ERR_SERVERFAULT = 10006,
NFS4ERR_BADTYPE = 10007,
NFS4ERR_DELAY = 10008,
NFS4ERR_SAME = 10009,
NFS4ERR_DENIED = 10010,
NFS4ERR_EXPIRED = 10011,
NFS4ERR_LOCKED = 10012,
NFS4ERR_GRACE = 10013,
NFS4ERR_FHEXPIRED = 10014,
NFS4ERR_SHARE_DENIED = 10015,
NFS4ERR_WRONGSEC = 10016,
NFS4ERR_CLID_INUSE = 10017,
NFS4ERR_RESOURCE = 10018,
NFS4ERR_MOVED = 10019,
NFS4ERR_NOFILEHANDLE = 10020,
NFS4ERR_MINOR_VERS_MISMATCH = 10021,
NFS4ERR_STALE_CLIENTID = 10022,
NFS4ERR_STALE_STATEID = 10023,
NFS4ERR_OLD_STATEID = 10024,
NFS4ERR_BAD_STATEID = 10025,
NFS4ERR_BAD_SEQID = 10026,
NFS4ERR_NOT_SAME = 10027,
NFS4ERR_LOCK_RANGE = 10028,
NFS4ERR_SYMLINK = 10029,
NFS4ERR_RESTOREFH = 10030,
NFS4ERR_LEASE_MOVED = 10031,
NFS4ERR_ATTRNOTSUPP = 10032,
NFS4ERR_NO_GRACE = 10033,
NFS4ERR_RECLAIM_BAD = 10034,
NFS4ERR_RECLAIM_CONFLICT = 10035,
NFS4ERR_BADXDR = 10036,
NFS4ERR_LOCKS_HELD = 10037,
NFS4ERR_OPENMODE = 10038,
NFS4ERR_BADOWNER = 10039,
NFS4ERR_BADCHAR = 10040,
NFS4ERR_BADNAME = 10041,
NFS4ERR_BAD_RANGE = 10042,
NFS4ERR_LOCK_NOTSUPP = 10043,
NFS4ERR_OP_ILLEGAL = 10044,
NFS4ERR_DEADLOCK = 10045,
NFS4ERR_FILE_OPEN = 10046,
NFS4ERR_ADMIN_REVOKED = 10047,
NFS4ERR_CB_PATH_DOWN = 10048
};
/* /*
* Note: NF4BAD is not actually part of the protocol; it is just used * Note: NF4BAD is not actually part of the protocol; it is just used
* internally by nfsd. * internally by nfsd.
......
...@@ -571,7 +571,7 @@ extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struc ...@@ -571,7 +571,7 @@ extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struc
extern void nfs4_put_state_owner(struct nfs4_state_owner *); extern void nfs4_put_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *); extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_increment_seqid(u32 status, struct nfs4_state_owner *sp); extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
struct nfs4_mount_data; struct nfs4_mount_data;
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment