1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* miscellaneous bits 3 * 4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/errno.h> 11 #include <crypto/krb5.h> 12 #include "internal.h" 13 #include "afs_fs.h" 14 #include "protocol_uae.h" 15 16 /* 17 * convert an AFS abort code to a Linux error number 18 */ 19 int afs_abort_to_error(u32 abort_code) 20 { 21 switch (abort_code) { 22 /* Low errno codes inserted into abort namespace */ 23 case 13: return -EACCES; 24 case 27: return -EFBIG; 25 case 30: return -EROFS; 26 27 /* VICE "special error" codes; 101 - 111 */ 28 case VSALVAGE: return -EIO; 29 case VNOVNODE: return -ENOENT; 30 case VNOVOL: return -ENOMEDIUM; 31 case VVOLEXISTS: return -EEXIST; 32 case VNOSERVICE: return -EIO; 33 case VOFFLINE: return -ENOENT; 34 case VONLINE: return -EEXIST; 35 case VDISKFULL: return -ENOSPC; 36 case VOVERQUOTA: return -EDQUOT; 37 case VBUSY: return -EBUSY; 38 case VMOVED: return -ENXIO; 39 40 /* Volume Location server errors */ 41 case AFSVL_IDEXIST: return -EEXIST; 42 case AFSVL_IO: return -EREMOTEIO; 43 case AFSVL_NAMEEXIST: return -EEXIST; 44 case AFSVL_CREATEFAIL: return -EREMOTEIO; 45 case AFSVL_NOENT: return -ENOMEDIUM; 46 case AFSVL_EMPTY: return -ENOMEDIUM; 47 case AFSVL_ENTDELETED: return -ENOMEDIUM; 48 case AFSVL_BADNAME: return -EINVAL; 49 case AFSVL_BADINDEX: return -EINVAL; 50 case AFSVL_BADVOLTYPE: return -EINVAL; 51 case AFSVL_BADSERVER: return -EINVAL; 52 case AFSVL_BADPARTITION: return -EINVAL; 53 case AFSVL_REPSFULL: return -EFBIG; 54 case AFSVL_NOREPSERVER: return -ENOENT; 55 case AFSVL_DUPREPSERVER: return -EEXIST; 56 case AFSVL_RWNOTFOUND: return -ENOENT; 57 case AFSVL_BADREFCOUNT: return -EINVAL; 58 case AFSVL_SIZEEXCEEDED: return -EINVAL; 59 case AFSVL_BADENTRY: return -EINVAL; 60 case AFSVL_BADVOLIDBUMP: return -EINVAL; 61 case AFSVL_IDALREADYHASHED: return -EINVAL; 62 case AFSVL_ENTRYLOCKED: return -EBUSY; 63 case AFSVL_BADVOLOPER: return -EBADRQC; 64 case AFSVL_BADRELLOCKTYPE: return -EINVAL; 65 case AFSVL_RERELEASE: return -EREMOTEIO; 66 case AFSVL_BADSERVERFLAG: return -EINVAL; 67 case AFSVL_PERM: return -EACCES; 68 case AFSVL_NOMEM: return -EREMOTEIO; 69 70 /* Unified AFS error table */ 71 case UAEPERM: return -EPERM; 72 case UAENOENT: return -ENOENT; 73 case UAEAGAIN: return -EAGAIN; 74 case UAEACCES: return -EACCES; 75 case UAEBUSY: return -EBUSY; 76 case UAEEXIST: return -EEXIST; 77 case UAENOTDIR: return -ENOTDIR; 78 case UAEISDIR: return -EISDIR; 79 case UAEFBIG: return -EFBIG; 80 case UAENOSPC: return -ENOSPC; 81 case UAEROFS: return -EROFS; 82 case UAEMLINK: return -EMLINK; 83 case UAEDEADLK: return -EDEADLK; 84 case UAENAMETOOLONG: return -ENAMETOOLONG; 85 case UAENOLCK: return -ENOLCK; 86 case UAENOTEMPTY: return -ENOTEMPTY; 87 case UAELOOP: return -ELOOP; 88 case UAEOVERFLOW: return -EOVERFLOW; 89 case UAENOMEDIUM: return -ENOMEDIUM; 90 case UAEDQUOT: return -EDQUOT; 91 92 /* RXKAD abort codes; from include/rxrpc/packet.h. ET "RXK" == 0x1260B00 */ 93 case RXKADINCONSISTENCY: return -EPROTO; 94 case RXKADPACKETSHORT: return -EPROTO; 95 case RXKADLEVELFAIL: return -EKEYREJECTED; 96 case RXKADTICKETLEN: return -EKEYREJECTED; 97 case RXKADOUTOFSEQUENCE: return -EPROTO; 98 case RXKADNOAUTH: return -EKEYREJECTED; 99 case RXKADBADKEY: return -EKEYREJECTED; 100 case RXKADBADTICKET: return -EKEYREJECTED; 101 case RXKADUNKNOWNKEY: return -EKEYREJECTED; 102 case RXKADEXPIRED: return -EKEYEXPIRED; 103 case RXKADSEALEDINCON: return -EKEYREJECTED; 104 case RXKADDATALEN: return -EKEYREJECTED; 105 case RXKADILLEGALLEVEL: return -EKEYREJECTED; 106 107 case RXGK_INCONSISTENCY: return -EPROTO; 108 case RXGK_PACKETSHORT: return -EPROTO; 109 case RXGK_BADCHALLENGE: return -EPROTO; 110 case RXGK_SEALEDINCON: return -EKEYREJECTED; 111 case RXGK_NOTAUTH: return -EKEYREJECTED; 112 case RXGK_EXPIRED: return -EKEYEXPIRED; 113 case RXGK_BADLEVEL: return -EKEYREJECTED; 114 case RXGK_BADKEYNO: return -EKEYREJECTED; 115 case RXGK_NOTRXGK: return -EKEYREJECTED; 116 case RXGK_UNSUPPORTED: return -EKEYREJECTED; 117 case RXGK_GSSERROR: return -EKEYREJECTED; 118 #ifdef RXGK_BADETYPE 119 case RXGK_BADETYPE: return -ENOPKG; 120 #endif 121 #ifdef RXGK_BADTOKEN 122 case RXGK_BADTOKEN: return -EKEYREJECTED; 123 #endif 124 #ifdef RXGK_BADETYPE 125 case RXGK_DATALEN: return -EPROTO; 126 #endif 127 #ifdef RXGK_BADQOP 128 case RXGK_BADQOP: return -EKEYREJECTED; 129 #endif 130 131 case KRB5_PROG_KEYTYPE_NOSUPP: return -ENOPKG; 132 133 case RXGEN_OPCODE: return -ENOTSUPP; 134 135 default: return -EREMOTEIO; 136 } 137 } 138 139 /* 140 * Select the error to report from a set of errors. 141 */ 142 void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code) 143 { 144 switch (error) { 145 case 0: 146 e->aborted = false; 147 e->error = 0; 148 return; 149 default: 150 if (e->error == -ETIMEDOUT || 151 e->error == -ETIME) 152 return; 153 fallthrough; 154 case -ETIMEDOUT: 155 case -ETIME: 156 if (e->error == -ENOMEM || 157 e->error == -ENONET) 158 return; 159 fallthrough; 160 case -ENOMEM: 161 case -ENONET: 162 if (e->error == -ERFKILL) 163 return; 164 fallthrough; 165 case -ERFKILL: 166 if (e->error == -EADDRNOTAVAIL) 167 return; 168 fallthrough; 169 case -EADDRNOTAVAIL: 170 if (e->error == -ENETUNREACH) 171 return; 172 fallthrough; 173 case -ENETUNREACH: 174 if (e->error == -EHOSTUNREACH) 175 return; 176 fallthrough; 177 case -EHOSTUNREACH: 178 if (e->error == -EHOSTDOWN) 179 return; 180 fallthrough; 181 case -EHOSTDOWN: 182 if (e->error == -ECONNREFUSED) 183 return; 184 fallthrough; 185 case -ECONNREFUSED: 186 if (e->error == -ECONNRESET) 187 return; 188 fallthrough; 189 case -ECONNRESET: /* Responded, but call expired. */ 190 if (e->responded) 191 return; 192 e->error = error; 193 e->aborted = false; 194 return; 195 196 case -ECONNABORTED: 197 e->error = afs_abort_to_error(abort_code); 198 e->aborted = true; 199 e->responded = true; 200 return; 201 case -ENETRESET: /* Responded, but we seem to have changed address */ 202 e->aborted = false; 203 e->responded = true; 204 e->error = error; 205 return; 206 } 207 } 208