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