common.c 5.4 KB

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