Loading...
Note: File does not exist in v4.10.11.
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 */
11static 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, -EIO },
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};
49
50/**
51 * nfs_stat_to_errno - convert an NFS status code to a local errno
52 * @status: NFS status code to convert
53 *
54 * Returns a local errno value, or -EIO if the NFS status code is
55 * not recognized. This function is used jointly by NFSv2 and NFSv3.
56 */
57int nfs_stat_to_errno(enum nfs_stat status)
58{
59 int i;
60
61 for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) {
62 if (nfs_errtbl[i].stat == (int)status)
63 return nfs_errtbl[i].errno;
64 }
65 return -EIO;
66}
67EXPORT_SYMBOL_GPL(nfs_stat_to_errno);
68
69/*
70 * We need to translate between nfs v4 status return values and
71 * the local errno values which may not be the same.
72 *
73 * nfs4_errtbl_common[] is used before more specialized mappings
74 * available in nfs4_errtbl[] or nfs4_errtbl_localio[].
75 */
76static const struct {
77 int stat;
78 int errno;
79} nfs4_errtbl_common[] = {
80 { NFS4_OK, 0 },
81 { NFS4ERR_PERM, -EPERM },
82 { NFS4ERR_NOENT, -ENOENT },
83 { NFS4ERR_IO, -EIO },
84 { NFS4ERR_NXIO, -ENXIO },
85 { NFS4ERR_ACCESS, -EACCES },
86 { NFS4ERR_EXIST, -EEXIST },
87 { NFS4ERR_XDEV, -EXDEV },
88 { NFS4ERR_NOTDIR, -ENOTDIR },
89 { NFS4ERR_ISDIR, -EISDIR },
90 { NFS4ERR_INVAL, -EINVAL },
91 { NFS4ERR_FBIG, -EFBIG },
92 { NFS4ERR_NOSPC, -ENOSPC },
93 { NFS4ERR_ROFS, -EROFS },
94 { NFS4ERR_MLINK, -EMLINK },
95 { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG },
96 { NFS4ERR_NOTEMPTY, -ENOTEMPTY },
97 { NFS4ERR_DQUOT, -EDQUOT },
98 { NFS4ERR_STALE, -ESTALE },
99 { NFS4ERR_BADHANDLE, -EBADHANDLE },
100 { NFS4ERR_BAD_COOKIE, -EBADCOOKIE },
101 { NFS4ERR_NOTSUPP, -ENOTSUPP },
102 { NFS4ERR_TOOSMALL, -ETOOSMALL },
103 { NFS4ERR_BADTYPE, -EBADTYPE },
104 { NFS4ERR_SYMLINK, -ELOOP },
105 { NFS4ERR_DEADLOCK, -EDEADLK },
106};
107
108static const struct {
109 int stat;
110 int errno;
111} nfs4_errtbl[] = {
112 { NFS4ERR_SERVERFAULT, -EREMOTEIO },
113 { NFS4ERR_LOCKED, -EAGAIN },
114 { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP },
115 { NFS4ERR_NOXATTR, -ENODATA },
116 { NFS4ERR_XATTR2BIG, -E2BIG },
117};
118
119/*
120 * Convert an NFS error code to a local one.
121 * This one is used by NFSv4.
122 */
123int nfs4_stat_to_errno(int stat)
124{
125 int i;
126
127 /* First check nfs4_errtbl_common */
128 for (i = 0; i < ARRAY_SIZE(nfs4_errtbl_common); i++) {
129 if (nfs4_errtbl_common[i].stat == stat)
130 return nfs4_errtbl_common[i].errno;
131 }
132 /* Then check nfs4_errtbl */
133 for (i = 0; i < ARRAY_SIZE(nfs4_errtbl); i++) {
134 if (nfs4_errtbl[i].stat == stat)
135 return nfs4_errtbl[i].errno;
136 }
137 if (stat <= 10000 || stat > 10100) {
138 /* The server is looney tunes. */
139 return -EREMOTEIO;
140 }
141 /* If we cannot translate the error, the recovery routines should
142 * handle it.
143 * Note: remaining NFSv4 error codes have values > 10000, so should
144 * not conflict with native Linux error codes.
145 */
146 return -stat;
147}
148EXPORT_SYMBOL_GPL(nfs4_stat_to_errno);
149
150/*
151 * This table is useful for conversion from local errno to NFS error.
152 * It provides more logically correct mappings for use with LOCALIO
153 * (which is focused on converting from errno to NFS status).
154 */
155static const struct {
156 int stat;
157 int errno;
158} nfs4_errtbl_localio[] = {
159 /* Map errors differently than nfs4_errtbl */
160 { NFS4ERR_IO, -EREMOTEIO },
161 { NFS4ERR_DELAY, -EAGAIN },
162 { NFS4ERR_FBIG, -E2BIG },
163 /* Map errors not handled by nfs4_errtbl */
164 { NFS4ERR_STALE, -EBADF },
165 { NFS4ERR_STALE, -EOPENSTALE },
166 { NFS4ERR_DELAY, -ETIMEDOUT },
167 { NFS4ERR_DELAY, -ERESTARTSYS },
168 { NFS4ERR_DELAY, -ENOMEM },
169 { NFS4ERR_IO, -ETXTBSY },
170 { NFS4ERR_IO, -EBUSY },
171 { NFS4ERR_SERVERFAULT, -ESERVERFAULT },
172 { NFS4ERR_SERVERFAULT, -ENFILE },
173 { NFS4ERR_IO, -EUCLEAN },
174 { NFS4ERR_PERM, -ENOKEY },
175};
176
177/*
178 * Convert an errno to an NFS error code for LOCALIO.
179 */
180__u32 nfs_localio_errno_to_nfs4_stat(int errno)
181{
182 int i;
183
184 /* First check nfs4_errtbl_common */
185 for (i = 0; i < ARRAY_SIZE(nfs4_errtbl_common); i++) {
186 if (nfs4_errtbl_common[i].errno == errno)
187 return nfs4_errtbl_common[i].stat;
188 }
189 /* Then check nfs4_errtbl_localio */
190 for (i = 0; i < ARRAY_SIZE(nfs4_errtbl_localio); i++) {
191 if (nfs4_errtbl_localio[i].errno == errno)
192 return nfs4_errtbl_localio[i].stat;
193 }
194 /* If we cannot translate the error, the recovery routines should
195 * handle it.
196 * Note: remaining NFSv4 error codes have values > 10000, so should
197 * not conflict with native Linux error codes.
198 */
199 return NFS4ERR_SERVERFAULT;
200}
201EXPORT_SYMBOL_GPL(nfs_localio_errno_to_nfs4_stat);