1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/module.h>
4 #include <linux/nfs_common.h>
5 #include <linux/nfs4.h>
6
7 /*
8 * We need to translate between nfs status return values and
9 * the local errno values which may not be the same.
10 */
11 static const struct {
12 int stat;
13 int errno;
14 } nfs_errtbl[] = {
15 { NFS_OK, 0 },
16 { NFSERR_PERM, -EPERM },
17 { NFSERR_NOENT, -ENOENT },
18 { NFSERR_IO, -errno_NFSERR_IO},
19 { NFSERR_NXIO, -ENXIO },
20 /* { NFSERR_EAGAIN, -EAGAIN }, */
21 { NFSERR_ACCES, -EACCES },
22 { NFSERR_EXIST, -EEXIST },
23 { NFSERR_XDEV, -EXDEV },
24 { NFSERR_NODEV, -ENODEV },
25 { NFSERR_NOTDIR, -ENOTDIR },
26 { NFSERR_ISDIR, -EISDIR },
27 { NFSERR_INVAL, -EINVAL },
28 { NFSERR_FBIG, -EFBIG },
29 { NFSERR_NOSPC, -ENOSPC },
30 { NFSERR_ROFS, -EROFS },
31 { NFSERR_MLINK, -EMLINK },
32 { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
33 { NFSERR_NOTEMPTY, -ENOTEMPTY },
34 { NFSERR_DQUOT, -EDQUOT },
35 { NFSERR_STALE, -ESTALE },
36 { NFSERR_REMOTE, -EREMOTE },
37 #ifdef EWFLUSH
38 { NFSERR_WFLUSH, -EWFLUSH },
39 #endif
40 { NFSERR_BADHANDLE, -EBADHANDLE },
41 { NFSERR_NOT_SYNC, -ENOTSYNC },
42 { NFSERR_BAD_COOKIE, -EBADCOOKIE },
43 { NFSERR_NOTSUPP, -ENOTSUPP },
44 { NFSERR_TOOSMALL, -ETOOSMALL },
45 { NFSERR_SERVERFAULT, -EREMOTEIO },
46 { NFSERR_BADTYPE, -EBADTYPE },
47 { NFSERR_JUKEBOX, -EJUKEBOX },
48 { -1, -EIO }
49 };
50
51 /**
52 * nfs_stat_to_errno - convert an NFS status code to a local errno
53 * @status: NFS status code to convert
54 *
55 * Returns a local errno value, or -EIO if the NFS status code is
56 * not recognized. This function is used jointly by NFSv2 and NFSv3.
57 */
nfs_stat_to_errno(enum nfs_stat status)58 int nfs_stat_to_errno(enum nfs_stat status)
59 {
60 int i;
61
62 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
63 if (nfs_errtbl[i].stat == (int)status)
64 return nfs_errtbl[i].errno;
65 }
66 return nfs_errtbl[i].errno;
67 }
68 EXPORT_SYMBOL_GPL(nfs_stat_to_errno);
69
70 /*
71 * We need to translate between nfs v4 status return values and
72 * the local errno values which may not be the same.
73 */
74 static const struct {
75 int stat;
76 int errno;
77 } nfs4_errtbl[] = {
78 { NFS4_OK, 0 },
79 { NFS4ERR_PERM, -EPERM },
80 { NFS4ERR_NOENT, -ENOENT },
81 { NFS4ERR_IO, -errno_NFSERR_IO},
82 { NFS4ERR_NXIO, -ENXIO },
83 { NFS4ERR_ACCESS, -EACCES },
84 { NFS4ERR_EXIST, -EEXIST },
85 { NFS4ERR_XDEV, -EXDEV },
86 { NFS4ERR_NOTDIR, -ENOTDIR },
87 { NFS4ERR_ISDIR, -EISDIR },
88 { NFS4ERR_INVAL, -EINVAL },
89 { NFS4ERR_FBIG, -EFBIG },
90 { NFS4ERR_NOSPC, -ENOSPC },
91 { NFS4ERR_ROFS, -EROFS },
92 { NFS4ERR_MLINK, -EMLINK },
93 { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG },
94 { NFS4ERR_NOTEMPTY, -ENOTEMPTY },
95 { NFS4ERR_DQUOT, -EDQUOT },
96 { NFS4ERR_STALE, -ESTALE },
97 { NFS4ERR_BADHANDLE, -EBADHANDLE },
98 { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
99 { NFS4ERR_NOTSUPP, -ENOTSUPP },
100 { NFS4ERR_TOOSMALL, -ETOOSMALL },
101 { NFS4ERR_SERVERFAULT, -EREMOTEIO },
102 { NFS4ERR_BADTYPE, -EBADTYPE },
103 { NFS4ERR_LOCKED, -EAGAIN },
104 { NFS4ERR_SYMLINK, -ELOOP },
105 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
106 { NFS4ERR_DEADLOCK, -EDEADLK },
107 { NFS4ERR_NOXATTR, -ENODATA },
108 { NFS4ERR_XATTR2BIG, -E2BIG },
109 { -1, -EIO }
110 };
111
112 /*
113 * Convert an NFS error code to a local one.
114 * This one is used by NFSv4.
115 */
nfs4_stat_to_errno(int stat)116 int nfs4_stat_to_errno(int stat)
117 {
118 int i;
119 for (i = 0; nfs4_errtbl[i].stat != -1; i++) {
120 if (nfs4_errtbl[i].stat == stat)
121 return nfs4_errtbl[i].errno;
122 }
123 if (stat <= 10000 || stat > 10100) {
124 /* The server is looney tunes. */
125 return -EREMOTEIO;
126 }
127 /* If we cannot translate the error, the recovery routines should
128 * handle it.
129 * Note: remaining NFSv4 error codes have values > 10000, so should
130 * not conflict with native Linux error codes.
131 */
132 return -stat;
133 }
134 EXPORT_SYMBOL_GPL(nfs4_stat_to_errno);
135