common.c 5.4 KB

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