PageRenderTime 25ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/net/9p/error.c

https://github.com/kvaneesh/linux
C | 232 lines | 180 code | 16 blank | 36 comment | 8 complexity | 62520fd9d54ad88987251941b7fa196d MD5 | raw file
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/fs/9p/error.c
  4. *
  5. * Error string handling
  6. *
  7. * Plan 9 uses error strings, Unix uses error numbers. These functions
  8. * try to help manage that and provide for dynamically adding error
  9. * mappings.
  10. *
  11. * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  12. * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  13. */
  14. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15. #include <linux/module.h>
  16. #include <linux/list.h>
  17. #include <linux/jhash.h>
  18. #include <linux/errno.h>
  19. #include <net/9p/9p.h>
  20. /**
  21. * struct errormap - map string errors from Plan 9 to Linux numeric ids
  22. * @name: string sent over 9P
  23. * @val: numeric id most closely representing @name
  24. * @namelen: length of string
  25. * @list: hash-table list for string lookup
  26. */
  27. struct errormap {
  28. char *name;
  29. int val;
  30. int namelen;
  31. struct hlist_node list;
  32. };
  33. #define ERRHASHSZ 32
  34. static struct hlist_head hash_errmap[ERRHASHSZ];
  35. /* FixMe - reduce to a reasonable size */
  36. static struct errormap errmap[] = {
  37. {"Operation not permitted", EPERM},
  38. {"wstat prohibited", EPERM},
  39. {"No such file or directory", ENOENT},
  40. {"directory entry not found", ENOENT},
  41. {"file not found", ENOENT},
  42. {"Interrupted system call", EINTR},
  43. {"Input/output error", EIO},
  44. {"No such device or address", ENXIO},
  45. {"Argument list too long", E2BIG},
  46. {"Bad file descriptor", EBADF},
  47. {"Resource temporarily unavailable", EAGAIN},
  48. {"Cannot allocate memory", ENOMEM},
  49. {"Permission denied", EACCES},
  50. {"Bad address", EFAULT},
  51. {"Block device required", ENOTBLK},
  52. {"Device or resource busy", EBUSY},
  53. {"File exists", EEXIST},
  54. {"Invalid cross-device link", EXDEV},
  55. {"No such device", ENODEV},
  56. {"Not a directory", ENOTDIR},
  57. {"Is a directory", EISDIR},
  58. {"Invalid argument", EINVAL},
  59. {"Too many open files in system", ENFILE},
  60. {"Too many open files", EMFILE},
  61. {"Text file busy", ETXTBSY},
  62. {"File too large", EFBIG},
  63. {"No space left on device", ENOSPC},
  64. {"Illegal seek", ESPIPE},
  65. {"Read-only file system", EROFS},
  66. {"Too many links", EMLINK},
  67. {"Broken pipe", EPIPE},
  68. {"Numerical argument out of domain", EDOM},
  69. {"Numerical result out of range", ERANGE},
  70. {"Resource deadlock avoided", EDEADLK},
  71. {"File name too long", ENAMETOOLONG},
  72. {"No locks available", ENOLCK},
  73. {"Function not implemented", ENOSYS},
  74. {"Directory not empty", ENOTEMPTY},
  75. {"Too many levels of symbolic links", ELOOP},
  76. {"No message of desired type", ENOMSG},
  77. {"Identifier removed", EIDRM},
  78. {"No data available", ENODATA},
  79. {"Machine is not on the network", ENONET},
  80. {"Package not installed", ENOPKG},
  81. {"Object is remote", EREMOTE},
  82. {"Link has been severed", ENOLINK},
  83. {"Communication error on send", ECOMM},
  84. {"Protocol error", EPROTO},
  85. {"Bad message", EBADMSG},
  86. {"File descriptor in bad state", EBADFD},
  87. {"Streams pipe error", ESTRPIPE},
  88. {"Too many users", EUSERS},
  89. {"Socket operation on non-socket", ENOTSOCK},
  90. {"Message too long", EMSGSIZE},
  91. {"Protocol not available", ENOPROTOOPT},
  92. {"Protocol not supported", EPROTONOSUPPORT},
  93. {"Socket type not supported", ESOCKTNOSUPPORT},
  94. {"Operation not supported", EOPNOTSUPP},
  95. {"Protocol family not supported", EPFNOSUPPORT},
  96. {"Network is down", ENETDOWN},
  97. {"Network is unreachable", ENETUNREACH},
  98. {"Network dropped connection on reset", ENETRESET},
  99. {"Software caused connection abort", ECONNABORTED},
  100. {"Connection reset by peer", ECONNRESET},
  101. {"No buffer space available", ENOBUFS},
  102. {"Transport endpoint is already connected", EISCONN},
  103. {"Transport endpoint is not connected", ENOTCONN},
  104. {"Cannot send after transport endpoint shutdown", ESHUTDOWN},
  105. {"Connection timed out", ETIMEDOUT},
  106. {"Connection refused", ECONNREFUSED},
  107. {"Host is down", EHOSTDOWN},
  108. {"No route to host", EHOSTUNREACH},
  109. {"Operation already in progress", EALREADY},
  110. {"Operation now in progress", EINPROGRESS},
  111. {"Is a named type file", EISNAM},
  112. {"Remote I/O error", EREMOTEIO},
  113. {"Disk quota exceeded", EDQUOT},
  114. /* errors from fossil, vacfs, and u9fs */
  115. {"fid unknown or out of range", EBADF},
  116. {"permission denied", EACCES},
  117. {"file does not exist", ENOENT},
  118. {"authentication failed", ECONNREFUSED},
  119. {"bad offset in directory read", ESPIPE},
  120. {"bad use of fid", EBADF},
  121. {"wstat can't convert between files and directories", EPERM},
  122. {"directory is not empty", ENOTEMPTY},
  123. {"file exists", EEXIST},
  124. {"file already exists", EEXIST},
  125. {"file or directory already exists", EEXIST},
  126. {"fid already in use", EBADF},
  127. {"file in use", ETXTBSY},
  128. {"i/o error", EIO},
  129. {"file already open for I/O", ETXTBSY},
  130. {"illegal mode", EINVAL},
  131. {"illegal name", ENAMETOOLONG},
  132. {"not a directory", ENOTDIR},
  133. {"not a member of proposed group", EPERM},
  134. {"not owner", EACCES},
  135. {"only owner can change group in wstat", EACCES},
  136. {"read only file system", EROFS},
  137. {"no access to special file", EPERM},
  138. {"i/o count too large", EIO},
  139. {"unknown group", EINVAL},
  140. {"unknown user", EINVAL},
  141. {"bogus wstat buffer", EPROTO},
  142. {"exclusive use file already open", EAGAIN},
  143. {"corrupted directory entry", EIO},
  144. {"corrupted file entry", EIO},
  145. {"corrupted block label", EIO},
  146. {"corrupted meta data", EIO},
  147. {"illegal offset", EINVAL},
  148. {"illegal path element", ENOENT},
  149. {"root of file system is corrupted", EIO},
  150. {"corrupted super block", EIO},
  151. {"protocol botch", EPROTO},
  152. {"file system is full", ENOSPC},
  153. {"file is in use", EAGAIN},
  154. {"directory entry is not allocated", ENOENT},
  155. {"file is read only", EROFS},
  156. {"file has been removed", EIDRM},
  157. {"only support truncation to zero length", EPERM},
  158. {"cannot remove root", EPERM},
  159. {"file too big", EFBIG},
  160. {"venti i/o error", EIO},
  161. /* these are not errors */
  162. {"u9fs rhostsauth: no authentication required", 0},
  163. {"u9fs authnone: no authentication required", 0},
  164. {NULL, -1}
  165. };
  166. /**
  167. * p9_error_init - preload mappings into hash list
  168. *
  169. */
  170. int p9_error_init(void)
  171. {
  172. struct errormap *c;
  173. int bucket;
  174. /* initialize hash table */
  175. for (bucket = 0; bucket < ERRHASHSZ; bucket++)
  176. INIT_HLIST_HEAD(&hash_errmap[bucket]);
  177. /* load initial error map into hash table */
  178. for (c = errmap; c->name != NULL; c++) {
  179. c->namelen = strlen(c->name);
  180. bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
  181. INIT_HLIST_NODE(&c->list);
  182. hlist_add_head(&c->list, &hash_errmap[bucket]);
  183. }
  184. return 1;
  185. }
  186. EXPORT_SYMBOL(p9_error_init);
  187. /**
  188. * p9_errstr2errno - convert error string to error number
  189. * @errstr: error string
  190. * @len: length of error string
  191. *
  192. */
  193. int p9_errstr2errno(char *errstr, int len)
  194. {
  195. int errno;
  196. struct errormap *c;
  197. int bucket;
  198. errno = 0;
  199. c = NULL;
  200. bucket = jhash(errstr, len, 0) % ERRHASHSZ;
  201. hlist_for_each_entry(c, &hash_errmap[bucket], list) {
  202. if (c->namelen == len && !memcmp(c->name, errstr, len)) {
  203. errno = c->val;
  204. break;
  205. }
  206. }
  207. if (errno == 0) {
  208. /* TODO: if error isn't found, add it dynamically */
  209. errstr[len] = 0;
  210. pr_err("%s: server reported unknown error %s\n",
  211. __func__, errstr);
  212. errno = ESERVERFAULT;
  213. }
  214. return -errno;
  215. }
  216. EXPORT_SYMBOL(p9_errstr2errno);