diff options
Diffstat (limited to '')
-rw-r--r-- | src/common/win32/errno.cc | 652 |
1 files changed, 652 insertions, 0 deletions
diff --git a/src/common/win32/errno.cc b/src/common/win32/errno.cc new file mode 100644 index 000000000..d0942fac9 --- /dev/null +++ b/src/common/win32/errno.cc @@ -0,0 +1,652 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2020 SUSE LINUX GmbH + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + + +#include <errno.h> +#include <stdlib.h> + +#include "include/int_types.h" +#include <ntdef.h> +#include <ntstatus.h> + +#include "include/compat.h" +#include "include/int_types.h" +#include "include/types.h" +#include "include/fs_types.h" + +// We're only converting errors defined in errno.h, not standard Windows +// system error codes that are usually retrievied using GetLastErrorCode(). +// TODO: consider converting WinSock2 (WSA*) error codes, which are quite +// similar to the errno.h ones. + +__u32 ceph_to_hostos_errno_unsigned(__u32 r) +{ + // using an array like like freebsd_errno.cc might be more readable but + // we have some large values defined by Boost. + switch(r) { + case 1: return EPERM; + case 2: return ENOENT; + case 3: return ESRCH; + case 4: return EINTR; + case 5: return EIO; + case 6: return ENXIO; + case 7: return E2BIG; + case 8: return ENOEXEC; + case 9: return EBADF; + case 10: return ECHILD; + // same as EWOULDBLOCK + case 11: return EAGAIN; + case 12: return ENOMEM; + case 13: return EACCES; + case 14: return EFAULT; + case 15: return ENOTBLK; + case 16: return EBUSY; + case 17: return EEXIST; + case 18: return EXDEV; + case 19: return ENODEV; + case 20: return ENOTDIR; + case 21: return EISDIR; + case 22: return EINVAL; + case 23: return ENFILE; + case 24: return EMFILE; + case 25: return ENOTTY; + case 26: return ETXTBSY; + case 27: return EFBIG; + case 28: return ENOSPC; + case 29: return ESPIPE; + case 30: return EROFS; + case 31: return EMLINK; + case 32: return EPIPE; + case 33: return EDOM; + case 34: return ERANGE; + // same as EDEADLK + case 35: return EDEADLOCK; + case 36: return ENAMETOOLONG; + case 37: return ENOLCK; + case 38: return ENOSYS; + case 39: return ENOTEMPTY; + case 40: return ELOOP; + case 42: return ENOMSG; + case 43: return EIDRM; + case 44: return ECHRNG; + case 45: return EL2NSYNC; + case 46: return EL3HLT; + case 47: return EL3RST; + case 48: return ELNRNG; + case 49: return EUNATCH; + case 50: return ENOCSI; + case 51: return EL2HLT; + case 52: return EBADE; + case 53: return EBADR; + case 54: return EXFULL; + case 55: return ENOANO; + case 56: return EBADRQC; + case 57: return EBADSLT; + case 59: return EBFONT; + case 60: return ENOSTR; + case 61: return ENODATA; + case 62: return ETIME; + case 63: return ENOSR; + case 64: return ENONET; + case 65: return ENOPKG; + case 66: return EREMOTE; + case 67: return ENOLINK; + case 68: return EADV; + case 69: return ESRMNT; + case 70: return ECOMM; + case 71: return EPROTO; + case 72: return EMULTIHOP; + case 73: return EDOTDOT; + case 74: return EBADMSG; + case 75: return EOVERFLOW; + case 76: return ENOTUNIQ; + case 77: return EBADFD; + case 78: return EREMCHG; + case 79: return ELIBACC; + case 80: return ELIBBAD; + case 81: return ELIBSCN; + case 82: return ELIBMAX; + case 83: return ELIBEXEC; + case 84: return EILSEQ; + case 85: return ERESTART; + case 86: return ESTRPIPE; + case 87: return EUSERS; + case 88: return ENOTSOCK; + case 89: return EDESTADDRREQ; + case 90: return EMSGSIZE; + case 91: return EPROTOTYPE; + case 92: return ENOPROTOOPT; + case 93: return EPROTONOSUPPORT; + case 94: return ESOCKTNOSUPPORT; + // same as ENOTSUP + case 95: return EOPNOTSUPP; + case 96: return EPFNOSUPPORT; + case 97: return EAFNOSUPPORT; + case 98: return EADDRINUSE; + case 99: return EADDRNOTAVAIL; + case 100: return ENETDOWN; + case 101: return ENETUNREACH; + case 102: return ENETRESET; + case 103: return ECONNABORTED; + case 104: return ECONNRESET; + case 105: return ENOBUFS; + case 106: return EISCONN; + case 107: return ENOTCONN; + case 108: return ESHUTDOWN; + case 109: return ETOOMANYREFS; + case 110: return ETIMEDOUT; + case 111: return ECONNREFUSED; + case 112: return EHOSTDOWN; + case 113: return EHOSTUNREACH; + case 114: return EALREADY; + case 115: return EINPROGRESS; + case 116: return ESTALE; + case 117: return EUCLEAN; + case 118: return ENOTNAM; + case 119: return ENAVAIL; + case 120: return EISNAM; + case 121: return EREMOTEIO; + case 122: return EDQUOT; + case 123: return ENOMEDIUM; + case 124: return EMEDIUMTYPE; + case 125: return ECANCELED; + case 126: return ENOKEY; + case 127: return EKEYEXPIRED; + case 128: return EKEYREVOKED; + case 129: return EKEYREJECTED; + case 130: return EOWNERDEAD; + case 131: return ENOTRECOVERABLE; + case 132: return ERFKILL; + case 133: return EHWPOISON; + default: + return r; + } +} + +__u32 hostos_to_ceph_errno_unsigned(__u32 r) { + // Windows errno -> Linux errno + switch(r) { + case EPERM: return 1; + case ENOENT: return 2; + case ESRCH: return 3; + case EINTR: return 4; + case EIO: return 5; + case ENXIO: return 6; + case E2BIG: return 7; + case ENOEXEC: return 8; + case EBADF: return 9; + case ECHILD: return 10; + case EAGAIN: return 11; + case EWOULDBLOCK: return 11; + case ENOMEM: return 12; + case EACCES: return 13; + case EFAULT: return 14; + case ENOTBLK: return 15; + case EBUSY: return 16; + case EEXIST: return 17; + case EXDEV: return 18; + case ENODEV: return 19; + case ENOTDIR: return 20; + case EISDIR: return 21; + case EINVAL: return 22; + case ENFILE: return 23; + case EMFILE: return 24; + case ENOTTY: return 25; + case ETXTBSY: return 26; + case EFBIG: return 27; + case ENOSPC: return 28; + case ESPIPE: return 29; + case EROFS: return 30; + case EMLINK: return 31; + case EPIPE: return 32; + case EDOM: return 33; + case ERANGE: return 34; + // same as EDEADLOCK + // case EDEADLK: return 35; + case EDEADLOCK: return 35; + case ENAMETOOLONG: return 36; + case ENOLCK: return 37; + case ENOSYS: return 38; + case ENOTEMPTY: return 39; + case ELOOP: return 40; + case ENOMSG: return 42; + case EIDRM: return 43; + case ECHRNG: return 44; + case EL2NSYNC: return 45; + case EL3HLT: return 46; + case EL3RST: return 47; + case ELNRNG: return 48; + case EUNATCH: return 49; + case ENOCSI: return 50; + case EL2HLT: return 51; + case EBADE: return 52; + case EBADR: return 53; + case EXFULL: return 54; + case ENOANO: return 55; + case EBADRQC: return 56; + case EBADSLT: return 57; + case EBFONT: return 59; + case ENOSTR: return 60; + case ENODATA: return 61; + case ETIME: return 62; + case ENOSR: return 63; + case ENONET: return 64; + case ENOPKG: return 65; + case EREMOTE: return 66; + case ENOLINK: return 67; + case EADV: return 68; + case ESRMNT: return 69; + case ECOMM: return 70; + case EPROTO: return 71; + case EMULTIHOP: return 72; + case EDOTDOT: return 73; + case EBADMSG: return 74; + case EOVERFLOW: return 75; + case ENOTUNIQ: return 76; + case EBADFD: return 77; + case EREMCHG: return 78; + case ELIBACC: return 79; + case ELIBBAD: return 80; + case ELIBSCN: return 81; + case ELIBMAX: return 82; + case ELIBEXEC: return 83; + case EILSEQ: return 84; + // compat.h defines ERESTART as EINTR + // case ERESTART: return 85; + case ESTRPIPE: return 86; + case EUSERS: return 87; + case ENOTSOCK: return 88; + case EDESTADDRREQ: return 89; + case EMSGSIZE: return 90; + case EPROTOTYPE: return 91; + case ENOPROTOOPT: return 92; + case EPROTONOSUPPORT: return 93; + case ESOCKTNOSUPPORT: return 94; + case EOPNOTSUPP: return 95; + case ENOTSUP: return 95; + case EPFNOSUPPORT: return 96; + case EAFNOSUPPORT: return 97; + case EADDRINUSE: return 98; + case EADDRNOTAVAIL: return 99; + case ENETDOWN: return 100; + case ENETUNREACH: return 101; + case ENETRESET: return 102; + case ECONNABORTED: return 103; + case ECONNRESET: return 104; + case ENOBUFS: return 105; + case EISCONN: return 106; + case ENOTCONN: return 107; + case ESHUTDOWN: return 108; + case ETOOMANYREFS: return 109; + case ETIMEDOUT: return 110; + case ECONNREFUSED: return 111; + case EHOSTDOWN: return 112; + case EHOSTUNREACH: return 113; + case EALREADY: return 114; + case EINPROGRESS: return 115; + case ESTALE: return 116; + case EUCLEAN: return 117; + case ENOTNAM: return 118; + case ENAVAIL: return 119; + case EISNAM: return 120; + case EREMOTEIO: return 121; + case EDQUOT: return 122; + case ENOMEDIUM: return 123; + case EMEDIUMTYPE: return 124; + case ECANCELED: return 125; + case ENOKEY: return 126; + case EKEYEXPIRED: return 127; + case EKEYREVOKED: return 128; + case EKEYREJECTED: return 129; + case EOWNERDEAD: return 130; + case ENOTRECOVERABLE: return 131; + case ERFKILL: return 132; + case EHWPOISON: return 133; + default: + return r; + } +} + +__s32 wsae_to_errno_unsigned(__s32 r) +{ + switch(r) { + case WSAEINTR: return EINTR; + case WSAEBADF: return EBADF; + case WSAEACCES: return EACCES; + case WSAEFAULT: return EFAULT; + case WSAEINVAL: return EINVAL; + case WSAEMFILE: return EMFILE; + // Linux defines WSAEWOULDBLOCK as EAGAIN, but not Windows headers. + // Since all ceph code uses EAGAIN instead of EWOULDBLOCK, we'll do + // the same here. + case WSAEWOULDBLOCK: return EAGAIN; + // Some functions (e.g. connect) can return WSAEWOULDBLOCK instead of + // EINPROGRESS. + case WSAEINPROGRESS: return EINPROGRESS; + case WSAEALREADY: return EALREADY; + case WSAENOTSOCK: return ENOTSOCK; + case WSAEDESTADDRREQ: return EDESTADDRREQ; + case WSAEMSGSIZE: return EMSGSIZE; + case WSAEPROTOTYPE: return EPROTOTYPE; + case WSAENOPROTOOPT: return ENOPROTOOPT; + case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT; + case WSAESOCKTNOSUPPORT: return ESOCKTNOSUPPORT; + case WSAEOPNOTSUPP: return EOPNOTSUPP; + case WSAEPFNOSUPPORT: return EPFNOSUPPORT; + case WSAEAFNOSUPPORT: return EAFNOSUPPORT; + case WSAEADDRINUSE: return EADDRINUSE; + case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL; + case WSAENETDOWN: return ENETDOWN; + case WSAENETUNREACH: return ENETUNREACH; + case WSAENETRESET: return ENETRESET; + case WSAECONNABORTED: return ECONNABORTED; + case WSAECONNRESET: return ECONNRESET; + case WSAENOBUFS: return ENOBUFS; + case WSAEISCONN: return EISCONN; + case WSAENOTCONN: return ENOTCONN; + case WSAESHUTDOWN: return ESHUTDOWN; + case WSAETOOMANYREFS: return ETOOMANYREFS; + case WSAETIMEDOUT: return ETIMEDOUT; + case WSAECONNREFUSED: return ECONNREFUSED; + case WSAELOOP: return ELOOP; + case WSAENAMETOOLONG: return ENAMETOOLONG; + case WSAEHOSTDOWN: return EHOSTDOWN; + case WSAEHOSTUNREACH: return EHOSTUNREACH; + case WSAENOTEMPTY: return ENOTEMPTY; + // case WSAEPROCLIM + case WSAEUSERS: return EUSERS; + case WSAEDQUOT: return EDQUOT; + case WSAESTALE: return ESTALE; + case WSAEREMOTE: return EREMOTE; + // case WSASYSNOTREADY + // case WSAVERNOTSUPPORTED + // case WSANOTINITIALISED + case WSAEDISCON: return ESHUTDOWN; + // case WSAENOMORE + case WSAECANCELLED: return ECANCELED; + // We might return EINVAL, but it's probably better if we propagate the + // original error code here. + // case WSAEINVALIDPROCTABLE + // case WSAEINVALIDPROVIDER + // case WSAEPROVIDERFAILEDINIT + // case WSASYSCALLFAILURE + // case WSASERVICE_NOT_FOUND: + // case WSATYPE_NOT_FOUND: + // case WSA_E_NO_MORE: + case WSA_E_CANCELLED: return ECANCELED; + case WSAEREFUSED: return ECONNREFUSED; + case WSAHOST_NOT_FOUND: return EHOSTUNREACH; + case WSATRY_AGAIN: return EAGAIN; + // case WSANO_RECOVERY + // case WSANO_DATA: + default: return r; + } +} + +// converts from linux errno values to host values +__s32 ceph_to_hostos_errno(__s32 r) +{ + int sign = (r < 0 ? -1 : 1); + return ceph_to_hostos_errno_unsigned(abs(r)) * sign; +} + +// converts Host OS errno values to linux/Ceph values +__s32 hostos_to_ceph_errno(__s32 r) +{ + int sign = (r < 0 ? -1 : 1); + return hostos_to_ceph_errno_unsigned(abs(r)) * sign; +} + +__s32 wsae_to_errno(__s32 r) +{ + int sign = (r < 0 ? -1 : 1); + return wsae_to_errno_unsigned(abs(r)) * sign; +} + +__u32 errno_to_ntstatus(__s32 r) { + // errno -> NTSTATUS + // In some cases, there might be more than one applicable NTSTATUS + // value or there might be none. Certain values can be overridden + // when the caller (or whoever is supposed to handle the error) is + // expecting a different NTSTATUS value. + r = abs(r); + + switch(r) { + case 0: return 0; + case EPERM: return STATUS_ACCESS_DENIED; + case ENOENT: return STATUS_OBJECT_NAME_NOT_FOUND; + case ESRCH: return STATUS_NOT_FOUND; + case EINTR: return STATUS_RETRY; + case EIO: return STATUS_DATA_ERROR; + case ENXIO: return STATUS_NOT_FOUND; + case E2BIG: return STATUS_FILE_TOO_LARGE; + case ENOEXEC: return STATUS_ACCESS_DENIED; + case EBADF: return STATUS_INVALID_HANDLE; + case ECHILD: return STATUS_INTERNAL_ERROR; + case EAGAIN: return STATUS_RETRY; + case EWOULDBLOCK: return STATUS_RETRY; + case ENOMEM: return STATUS_NO_MEMORY; + case EACCES: return STATUS_ACCESS_DENIED; + case EFAULT: return STATUS_INVALID_ADDRESS; + case ENOTBLK: return STATUS_BAD_DEVICE_TYPE; + case EBUSY: return STATUS_DEVICE_BUSY; + case EEXIST: return STATUS_OBJECT_NAME_COLLISION; + case EXDEV: return STATUS_NOT_SAME_DEVICE; + case ENODEV: return STATUS_SYSTEM_DEVICE_NOT_FOUND; + case ENOTDIR: return STATUS_NOT_A_DIRECTORY; + case EISDIR: return STATUS_FILE_IS_A_DIRECTORY; + case EINVAL: return STATUS_INVALID_PARAMETER; + case ENFILE: return STATUS_TOO_MANY_OPENED_FILES; + case EMFILE: return STATUS_TOO_MANY_OPENED_FILES; + case ENOTTY: return STATUS_INVALID_PARAMETER; + case ETXTBSY: return STATUS_DEVICE_BUSY; + case EFBIG: return STATUS_FILE_TOO_LARGE; + case ENOSPC: return STATUS_DISK_FULL; + case ESPIPE: return STATUS_INVALID_PARAMETER; + case EROFS: return STATUS_MEDIA_WRITE_PROTECTED; + case EMLINK: return STATUS_TOO_MANY_LINKS; + case EPIPE: return STATUS_PIPE_BROKEN; + case EDOM: return STATUS_INVALID_PARAMETER; + case ERANGE: return STATUS_INVALID_PARAMETER; + // same as EDEADLOCK + // case EDEADLK: return 35; + case EDEADLOCK: return STATUS_POSSIBLE_DEADLOCK; + case ENAMETOOLONG: return STATUS_NAME_TOO_LONG; + case ENOLCK: return STATUS_NOT_LOCKED; + case ENOSYS: return STATUS_NOT_IMPLEMENTED; + case ENOTEMPTY: return STATUS_DIRECTORY_NOT_EMPTY; + case ELOOP: return STATUS_TOO_MANY_LINKS; + case ENOMSG: return STATUS_MESSAGE_NOT_FOUND; + case EIDRM: return STATUS_INVALID_PARAMETER; + case ECHRNG: return STATUS_INVALID_PARAMETER; + case EL2NSYNC: return STATUS_INTERNAL_ERROR; + case EL3HLT: return STATUS_INTERNAL_ERROR; + case EL3RST: return STATUS_INTERNAL_ERROR; + case ELNRNG: return STATUS_INTERNAL_ERROR; + case EUNATCH: return STATUS_INTERNAL_ERROR; + case ENOCSI: return STATUS_INTERNAL_ERROR; + case EL2HLT: return STATUS_INTERNAL_ERROR; + case EBADE: return STATUS_INTERNAL_ERROR; + case EBADR: return STATUS_INVALID_HANDLE; + case EXFULL: return STATUS_DISK_FULL; + case ENOANO: return STATUS_INTERNAL_ERROR; + case EBADRQC: return STATUS_INVALID_PARAMETER; + case EBADSLT: return STATUS_INVALID_PARAMETER; + case EBFONT: return STATUS_INVALID_PARAMETER; + case ENOSTR: return STATUS_INVALID_PARAMETER; + case ENODATA: return STATUS_NOT_FOUND; + case ETIME: return STATUS_TIMEOUT; + case ENOSR: return STATUS_INSUFFICIENT_RESOURCES; + case ENONET: return STATUS_NETWORK_UNREACHABLE; + case ENOPKG: return STATUS_NO_SUCH_PACKAGE; + case EREMOTE: return STATUS_INVALID_PARAMETER; + case ENOLINK: return STATUS_INTERNAL_ERROR; + case EADV: return STATUS_INTERNAL_ERROR; + case ESRMNT: return STATUS_INTERNAL_ERROR; + case ECOMM: return STATUS_INTERNAL_ERROR; + case EPROTO: return STATUS_PROTOCOL_NOT_SUPPORTED; + case EMULTIHOP: return STATUS_INTERNAL_ERROR; + case EDOTDOT: return STATUS_INTERNAL_ERROR; + case EBADMSG: return STATUS_INVALID_PARAMETER; + case EOVERFLOW: return STATUS_BUFFER_OVERFLOW; + case ENOTUNIQ: return STATUS_DUPLICATE_NAME; + case EBADFD: return STATUS_INVALID_HANDLE; + case EREMCHG: return STATUS_FILE_RENAMED; + case ELIBACC: return STATUS_DLL_NOT_FOUND; + case ELIBBAD: return STATUS_BAD_DLL_ENTRYPOINT; + case ELIBSCN: return STATUS_BAD_DLL_ENTRYPOINT; + case ELIBMAX: return STATUS_TOO_MANY_OPENED_FILES; + case ELIBEXEC: return STATUS_INVALID_PARAMETER; + case EILSEQ: return STATUS_INVALID_PARAMETER; + // compat.h defines ERESTART as EINTR + // case ERESTART: return 85; + case ESTRPIPE: return STATUS_RETRY; + case EUSERS: return STATUS_TOO_MANY_SIDS; + case ENOTSOCK: return STATUS_INVALID_HANDLE; + case EDESTADDRREQ: return STATUS_INVALID_PARAMETER; + case EMSGSIZE: return STATUS_BUFFER_OVERFLOW; + case EPROTOTYPE: return STATUS_INVALID_PARAMETER; + case ENOPROTOOPT: return STATUS_PROTOCOL_NOT_SUPPORTED; + case EPROTONOSUPPORT: return STATUS_PROTOCOL_NOT_SUPPORTED; + case ESOCKTNOSUPPORT: return STATUS_NOT_SUPPORTED; + case EOPNOTSUPP: return STATUS_NOT_SUPPORTED; + case ENOTSUP: return STATUS_NOT_SUPPORTED; + case EPFNOSUPPORT: return STATUS_PROTOCOL_NOT_SUPPORTED; + case EAFNOSUPPORT: return STATUS_NOT_SUPPORTED; + case EADDRINUSE: return STATUS_ADDRESS_ALREADY_EXISTS; + case EADDRNOTAVAIL: return STATUS_INVALID_ADDRESS; + case ENETDOWN: return STATUS_NETWORK_UNREACHABLE; + case ENETUNREACH: return STATUS_NETWORK_UNREACHABLE; + case ENETRESET: return STATUS_CONNECTION_RESET; + case ECONNABORTED: return STATUS_CONNECTION_ABORTED; + case ECONNRESET: return STATUS_CONNECTION_DISCONNECTED; + case ENOBUFS: return STATUS_BUFFER_TOO_SMALL; + case EISCONN: return STATUS_CONNECTION_ACTIVE; + case ENOTCONN: return STATUS_CONNECTION_DISCONNECTED; + case ESHUTDOWN: return STATUS_SYSTEM_SHUTDOWN; + case ETOOMANYREFS: return STATUS_TOO_MANY_LINKS; + case ETIMEDOUT: return STATUS_TIMEOUT; + case ECONNREFUSED: return STATUS_CONNECTION_REFUSED; + case EHOSTDOWN: return STATUS_FILE_CLOSED; + case EHOSTUNREACH: return STATUS_HOST_UNREACHABLE; + case EALREADY: return STATUS_PENDING; + case EINPROGRESS: return STATUS_PENDING; + case ESTALE: return STATUS_INVALID_HANDLE; + case EUCLEAN: return STATUS_INVALID_PARAMETER; + case ENOTNAM: return STATUS_INVALID_PARAMETER; + case ENAVAIL: return STATUS_INVALID_PARAMETER; + case EISNAM: return STATUS_INVALID_PARAMETER; + case EREMOTEIO: return STATUS_DATA_ERROR; + case EDQUOT: return STATUS_QUOTA_EXCEEDED; + case ENOMEDIUM: return STATUS_NO_MEDIA; + case EMEDIUMTYPE: return STATUS_INVALID_PARAMETER; + case ECANCELED: return STATUS_REQUEST_CANCELED; + case ENOKEY: return STATUS_NO_USER_KEYS; + case EKEYEXPIRED: return STATUS_SMARTCARD_CERT_EXPIRED; + case EKEYREVOKED: return STATUS_IMAGE_CERT_REVOKED; + case EKEYREJECTED: return STATUS_ACCESS_DENIED; + case EOWNERDEAD: return STATUS_INTERNAL_ERROR; + case ENOTRECOVERABLE: return STATUS_INTERNAL_ERROR; + case ERFKILL: return STATUS_INTERNAL_ERROR; + case EHWPOISON: return STATUS_INTERNAL_ERROR; + default: + return STATUS_INTERNAL_ERROR; + } +} + +std::string win32_strerror(int err) +{ + // As opposed to dlerror messages, this has to be freed. + LPSTR msg = NULL; + DWORD msg_len = ::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + 0, + (LPSTR) &msg, + 0, + NULL); + + std::ostringstream msg_stream; + msg_stream << "(" << err << ") "; + if (!msg_len) { + msg_stream << "Unknown error"; + } + else { + msg_stream << msg; + ::LocalFree(msg); + } + return msg_stream.str(); +} + +std::string win32_lasterror_str() +{ + DWORD err = ::GetLastError(); + return win32_strerror(err); +} + +static const ceph::unordered_map<int,NTSTATUS> cephfs_errno_to_ntstatus = { + {CEPHFS_EBLOCKLISTED, STATUS_SYSTEM_SHUTDOWN}, + {CEPHFS_EPERM, STATUS_ACCESS_DENIED}, + {CEPHFS_ESTALE, STATUS_INVALID_HANDLE}, + {CEPHFS_ENOSPC, STATUS_DISK_FULL}, + {CEPHFS_ETIMEDOUT, STATUS_TIMEOUT}, + {CEPHFS_EIO, STATUS_DATA_ERROR}, + {CEPHFS_ENOTCONN, STATUS_CONNECTION_DISCONNECTED}, + {CEPHFS_EEXIST, STATUS_OBJECT_NAME_COLLISION}, + {CEPHFS_EINTR, STATUS_RETRY}, + {CEPHFS_EINVAL, STATUS_INVALID_PARAMETER}, + {CEPHFS_EBADF, STATUS_INVALID_HANDLE}, + {CEPHFS_EROFS, STATUS_MEDIA_WRITE_PROTECTED}, + {CEPHFS_EAGAIN, STATUS_RETRY}, + {CEPHFS_EACCES, STATUS_ACCESS_DENIED}, + {CEPHFS_ELOOP, STATUS_TOO_MANY_LINKS}, + {CEPHFS_EISDIR, STATUS_FILE_IS_A_DIRECTORY}, + {CEPHFS_ENOENT, STATUS_OBJECT_NAME_NOT_FOUND}, + {CEPHFS_ENOTDIR, STATUS_NOT_A_DIRECTORY}, + {CEPHFS_ENAMETOOLONG, STATUS_NAME_TOO_LONG}, + {CEPHFS_EBUSY, STATUS_DEVICE_BUSY}, + {CEPHFS_EDQUOT, STATUS_QUOTA_EXCEEDED}, + {CEPHFS_EFBIG, STATUS_FILE_TOO_LARGE}, + {CEPHFS_ERANGE, STATUS_INVALID_PARAMETER}, + {CEPHFS_ENXIO, STATUS_NOT_FOUND}, + {CEPHFS_ECANCELED, STATUS_REQUEST_CANCELED}, + {CEPHFS_ENODATA, STATUS_NOT_FOUND}, + {CEPHFS_EOPNOTSUPP, STATUS_NOT_SUPPORTED}, + {CEPHFS_EXDEV, STATUS_NOT_SAME_DEVICE}, + {CEPHFS_ENOMEM, STATUS_NO_MEMORY}, + {CEPHFS_ENOTRECOVERABLE, STATUS_INTERNAL_ERROR}, + {CEPHFS_ENOSYS, STATUS_NOT_IMPLEMENTED}, + {CEPHFS_ENOTEMPTY, STATUS_DIRECTORY_NOT_EMPTY}, + {CEPHFS_EDEADLK, STATUS_POSSIBLE_DEADLOCK}, + {CEPHFS_EDOM, STATUS_INVALID_PARAMETER}, + {CEPHFS_EMLINK, STATUS_TOO_MANY_LINKS}, + {CEPHFS_ETIME, STATUS_TIMEOUT}, + {CEPHFS_EOLDSNAPC, STATUS_DATA_ERROR} +}; + +__u32 cephfs_errno_to_ntstatus_map(int cephfs_errno) +{ + cephfs_errno = abs(cephfs_errno); + + if (cephfs_errno == 0) + return 0; + + auto it = cephfs_errno_to_ntstatus.find(cephfs_errno); + if (it != cephfs_errno_to_ntstatus.end()) + return it->second; + return STATUS_INTERNAL_ERROR; +} |