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 case RX_INVALID_OPERATION: return -ENOTSUPP; 135 136 default: return -EREMOTEIO; 137 } 138 } 139 140 /* 141 * Select the error to report from a set of errors. 142 */ 143 void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code) 144 { 145 switch (error) { 146 case 0: 147 e->aborted = false; 148 e->error = 0; 149 return; 150 default: 151 if (e->error == -ETIMEDOUT || 152 e->error == -ETIME) 153 return; 154 fallthrough; 155 case -ETIMEDOUT: 156 case -ETIME: 157 if (e->error == -ENOMEM || 158 e->error == -ENONET) 159 return; 160 fallthrough; 161 case -ENOMEM: 162 case -ENONET: 163 if (e->error == -ERFKILL) 164 return; 165 fallthrough; 166 case -ERFKILL: 167 if (e->error == -EADDRNOTAVAIL) 168 return; 169 fallthrough; 170 case -EADDRNOTAVAIL: 171 if (e->error == -ENETUNREACH) 172 return; 173 fallthrough; 174 case -ENETUNREACH: 175 if (e->error == -EHOSTUNREACH) 176 return; 177 fallthrough; 178 case -EHOSTUNREACH: 179 if (e->error == -EHOSTDOWN) 180 return; 181 fallthrough; 182 case -EHOSTDOWN: 183 if (e->error == -ECONNREFUSED) 184 return; 185 fallthrough; 186 case -ECONNREFUSED: 187 if (e->error == -ECONNRESET) 188 return; 189 fallthrough; 190 case -ECONNRESET: /* Responded, but call expired. */ 191 if (e->responded) 192 return; 193 e->error = error; 194 e->aborted = false; 195 return; 196 197 case -ECONNABORTED: 198 e->error = afs_abort_to_error(abort_code); 199 e->aborted = true; 200 e->responded = true; 201 return; 202 case -ENETRESET: /* Responded, but we seem to have changed address */ 203 e->aborted = false; 204 e->responded = true; 205 e->error = error; 206 return; 207 } 208 } 209