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, -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 */ 57 int 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 } 67 EXPORT_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 */ 76 static 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 108 static 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 */ 123 int 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 } 148 EXPORT_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 */ 155 static 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 } 201 EXPORT_SYMBOL_GPL(nfs_localio_errno_to_nfs4_stat); 202