0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0014
0015 #include <linux/module.h>
0016 #include <linux/list.h>
0017 #include <linux/jhash.h>
0018 #include <linux/errno.h>
0019 #include <net/9p/9p.h>
0020
0021
0022
0023
0024
0025
0026
0027
0028 struct errormap {
0029 char *name;
0030 int val;
0031
0032 int namelen;
0033 struct hlist_node list;
0034 };
0035
0036 #define ERRHASHSZ 32
0037 static struct hlist_head hash_errmap[ERRHASHSZ];
0038
0039
0040 static struct errormap errmap[] = {
0041 {"Operation not permitted", EPERM},
0042 {"wstat prohibited", EPERM},
0043 {"No such file or directory", ENOENT},
0044 {"directory entry not found", ENOENT},
0045 {"file not found", ENOENT},
0046 {"Interrupted system call", EINTR},
0047 {"Input/output error", EIO},
0048 {"No such device or address", ENXIO},
0049 {"Argument list too long", E2BIG},
0050 {"Bad file descriptor", EBADF},
0051 {"Resource temporarily unavailable", EAGAIN},
0052 {"Cannot allocate memory", ENOMEM},
0053 {"Permission denied", EACCES},
0054 {"Bad address", EFAULT},
0055 {"Block device required", ENOTBLK},
0056 {"Device or resource busy", EBUSY},
0057 {"File exists", EEXIST},
0058 {"Invalid cross-device link", EXDEV},
0059 {"No such device", ENODEV},
0060 {"Not a directory", ENOTDIR},
0061 {"Is a directory", EISDIR},
0062 {"Invalid argument", EINVAL},
0063 {"Too many open files in system", ENFILE},
0064 {"Too many open files", EMFILE},
0065 {"Text file busy", ETXTBSY},
0066 {"File too large", EFBIG},
0067 {"No space left on device", ENOSPC},
0068 {"Illegal seek", ESPIPE},
0069 {"Read-only file system", EROFS},
0070 {"Too many links", EMLINK},
0071 {"Broken pipe", EPIPE},
0072 {"Numerical argument out of domain", EDOM},
0073 {"Numerical result out of range", ERANGE},
0074 {"Resource deadlock avoided", EDEADLK},
0075 {"File name too long", ENAMETOOLONG},
0076 {"No locks available", ENOLCK},
0077 {"Function not implemented", ENOSYS},
0078 {"Directory not empty", ENOTEMPTY},
0079 {"Too many levels of symbolic links", ELOOP},
0080 {"No message of desired type", ENOMSG},
0081 {"Identifier removed", EIDRM},
0082 {"No data available", ENODATA},
0083 {"Machine is not on the network", ENONET},
0084 {"Package not installed", ENOPKG},
0085 {"Object is remote", EREMOTE},
0086 {"Link has been severed", ENOLINK},
0087 {"Communication error on send", ECOMM},
0088 {"Protocol error", EPROTO},
0089 {"Bad message", EBADMSG},
0090 {"File descriptor in bad state", EBADFD},
0091 {"Streams pipe error", ESTRPIPE},
0092 {"Too many users", EUSERS},
0093 {"Socket operation on non-socket", ENOTSOCK},
0094 {"Message too long", EMSGSIZE},
0095 {"Protocol not available", ENOPROTOOPT},
0096 {"Protocol not supported", EPROTONOSUPPORT},
0097 {"Socket type not supported", ESOCKTNOSUPPORT},
0098 {"Operation not supported", EOPNOTSUPP},
0099 {"Protocol family not supported", EPFNOSUPPORT},
0100 {"Network is down", ENETDOWN},
0101 {"Network is unreachable", ENETUNREACH},
0102 {"Network dropped connection on reset", ENETRESET},
0103 {"Software caused connection abort", ECONNABORTED},
0104 {"Connection reset by peer", ECONNRESET},
0105 {"No buffer space available", ENOBUFS},
0106 {"Transport endpoint is already connected", EISCONN},
0107 {"Transport endpoint is not connected", ENOTCONN},
0108 {"Cannot send after transport endpoint shutdown", ESHUTDOWN},
0109 {"Connection timed out", ETIMEDOUT},
0110 {"Connection refused", ECONNREFUSED},
0111 {"Host is down", EHOSTDOWN},
0112 {"No route to host", EHOSTUNREACH},
0113 {"Operation already in progress", EALREADY},
0114 {"Operation now in progress", EINPROGRESS},
0115 {"Is a named type file", EISNAM},
0116 {"Remote I/O error", EREMOTEIO},
0117 {"Disk quota exceeded", EDQUOT},
0118
0119 {"fid unknown or out of range", EBADF},
0120 {"permission denied", EACCES},
0121 {"file does not exist", ENOENT},
0122 {"authentication failed", ECONNREFUSED},
0123 {"bad offset in directory read", ESPIPE},
0124 {"bad use of fid", EBADF},
0125 {"wstat can't convert between files and directories", EPERM},
0126 {"directory is not empty", ENOTEMPTY},
0127 {"file exists", EEXIST},
0128 {"file already exists", EEXIST},
0129 {"file or directory already exists", EEXIST},
0130 {"fid already in use", EBADF},
0131 {"file in use", ETXTBSY},
0132 {"i/o error", EIO},
0133 {"file already open for I/O", ETXTBSY},
0134 {"illegal mode", EINVAL},
0135 {"illegal name", ENAMETOOLONG},
0136 {"not a directory", ENOTDIR},
0137 {"not a member of proposed group", EPERM},
0138 {"not owner", EACCES},
0139 {"only owner can change group in wstat", EACCES},
0140 {"read only file system", EROFS},
0141 {"no access to special file", EPERM},
0142 {"i/o count too large", EIO},
0143 {"unknown group", EINVAL},
0144 {"unknown user", EINVAL},
0145 {"bogus wstat buffer", EPROTO},
0146 {"exclusive use file already open", EAGAIN},
0147 {"corrupted directory entry", EIO},
0148 {"corrupted file entry", EIO},
0149 {"corrupted block label", EIO},
0150 {"corrupted meta data", EIO},
0151 {"illegal offset", EINVAL},
0152 {"illegal path element", ENOENT},
0153 {"root of file system is corrupted", EIO},
0154 {"corrupted super block", EIO},
0155 {"protocol botch", EPROTO},
0156 {"file system is full", ENOSPC},
0157 {"file is in use", EAGAIN},
0158 {"directory entry is not allocated", ENOENT},
0159 {"file is read only", EROFS},
0160 {"file has been removed", EIDRM},
0161 {"only support truncation to zero length", EPERM},
0162 {"cannot remove root", EPERM},
0163 {"file too big", EFBIG},
0164 {"venti i/o error", EIO},
0165
0166 {"u9fs rhostsauth: no authentication required", 0},
0167 {"u9fs authnone: no authentication required", 0},
0168 {NULL, -1}
0169 };
0170
0171
0172
0173
0174
0175
0176 int p9_error_init(void)
0177 {
0178 struct errormap *c;
0179 int bucket;
0180
0181
0182 for (bucket = 0; bucket < ERRHASHSZ; bucket++)
0183 INIT_HLIST_HEAD(&hash_errmap[bucket]);
0184
0185
0186 for (c = errmap; c->name; c++) {
0187 c->namelen = strlen(c->name);
0188 bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
0189 INIT_HLIST_NODE(&c->list);
0190 hlist_add_head(&c->list, &hash_errmap[bucket]);
0191 }
0192
0193 return 1;
0194 }
0195 EXPORT_SYMBOL(p9_error_init);
0196
0197
0198
0199
0200
0201
0202
0203
0204 int p9_errstr2errno(char *errstr, int len)
0205 {
0206 int errno;
0207 struct errormap *c;
0208 int bucket;
0209
0210 errno = 0;
0211 c = NULL;
0212 bucket = jhash(errstr, len, 0) % ERRHASHSZ;
0213 hlist_for_each_entry(c, &hash_errmap[bucket], list) {
0214 if (c->namelen == len && !memcmp(c->name, errstr, len)) {
0215 errno = c->val;
0216 break;
0217 }
0218 }
0219
0220 if (errno == 0) {
0221
0222 errstr[len] = 0;
0223 pr_err("%s: server reported unknown error %s\n",
0224 __func__, errstr);
0225 errno = ESERVERFAULT;
0226 }
0227
0228 return -errno;
0229 }
0230 EXPORT_SYMBOL(p9_errstr2errno);