X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fxattr.c;fp=src%2Fceph%2Fsrc%2Fcommon%2Fxattr.c;h=080bebcaafd81497867ab6113f3aeeb09f11c656;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/xattr.c b/src/ceph/src/common/xattr.c new file mode 100644 index 0000000..080bebc --- /dev/null +++ b/src/ceph/src/common/xattr.c @@ -0,0 +1,277 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 Stanislav Sedov + * + * 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. + */ + +#if defined(__FreeBSD__) +#include +#include +#include +#include +#include +#include +#elif defined(__linux__) +#include +#include +#elif defined(DARWIN) +#include +#else +#error "Your system is not supported!" +#endif + +#include "common/xattr.h" + +/* + * Sets extended attribute on a file. + * Returns 0 on success, -1 on failure. + */ +int +ceph_os_setxattr(const char *path, const char *name, + const void *value, size_t size) +{ + int error = -1; + +#if defined(__FreeBSD__) + error = extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, value, + size); + if (error > 0) + error = 0; +#elif defined(__linux__) + error = setxattr(path, name, value, size, 0); +#elif defined(DARWIN) + error = setxattr(path, name, value, size, 0 /* position */, 0); +#endif + + return (error); +} + +int +ceph_os_fsetxattr(int fd, const char *name, const void *value, + size_t size) +{ + int error = -1; + +#if defined(__FreeBSD__) + error = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size); + if (error > 0) + error = 0; +#elif defined(__linux__) + error = fsetxattr(fd, name, value, size, 0); +#elif defined(DARWIN) + error = fsetxattr(fd, name, value, size, 0, 0 /* no options should be indentical to Linux */ ); +#endif + + return (error); +} + +ssize_t +ceph_os_getxattr(const char *path, const char *name, +void *value, size_t size) +{ + ssize_t error = -1; + +#if defined(__FreeBSD__) + if (value == NULL || size == 0) { + error = extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, value, + size); + } else { + error = extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, NULL, + 0); + if (error > 0) { + if (error > size) { + errno = ERANGE; + error = -1; + } else { + error = extattr_get_file(path, EXTATTR_NAMESPACE_USER, + name, value, size); + } + } + } +#elif defined(__linux__) + error = getxattr(path, name, value, size); +#elif defined(DARWIN) + error = getxattr(path, name, value, size, 0 /* position */, 0); + /* ENOATTR and ENODATA have different values */ + if (error < 0 && errno == ENOATTR) + errno = ENODATA; +#endif + + return (error); +} + +ssize_t +ceph_os_fgetxattr(int fd, const char *name, void *value, + size_t size) +{ + ssize_t error = -1; + +#if defined(__FreeBSD__) + if (value == NULL || size == 0) { + error = extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, + size); + } else { + error = extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, NULL, + 0); + if (error > 0) { + if (error > size) { + errno = ERANGE; + error = -1; + } else { + error = extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, + name, value, size); + } + } + } +#elif defined(__linux__) + error = fgetxattr(fd, name, value, size); +#elif defined(DARWIN) + error = fgetxattr(fd, name, value, size, 0, 0 /* no options */); + /* ENOATTR and ENODATA have different values */ + if (error < 0 && errno == ENOATTR) + errno = ENODATA; +#endif + + return (error); +} + +ssize_t +ceph_os_listxattr(const char *path, char *list, size_t size) +{ + ssize_t error = -1; + +#if defined(__FreeBSD__) + /* + * XXX. The format of the list FreeBSD returns differs + * from the Linux ones. We have to perform the conversion. :-( + */ + char *newlist, *p, *p1; + + if (size != 0) { + newlist = malloc(size); + if (newlist != NULL) { + error = extattr_list_file(path, EXTATTR_NAMESPACE_USER, + newlist, size); + if (error > 0) { + p = newlist; + p1 = list; + while ((p - newlist) < error) { + uint8_t len = *(uint8_t *)p; + p++; + if ((p + len - newlist) > error) + break; + if (len > 0) { + bcopy(p, p1, len); + p += len; + p1 += len; + *p1++ = '\0'; + } + } + error = p1 - list; + } + free(newlist); + } + } else { + error = extattr_list_file(path, EXTATTR_NAMESPACE_USER, + list, size); + } +#elif defined(__linux__) + error = listxattr(path, list, size); +#elif defined(DARWIN) + error = listxattr(path, list, size, 0); +#endif + + return (error); +} + +ssize_t +ceph_os_flistxattr(int fd, char *list, size_t size) +{ + ssize_t error = -1; + +#if defined(__FreeBSD__) + /* + * XXX. The format of the list FreeBSD returns differs + * from the Linux ones. We have to perform the conversion. :-( + */ + char *newlist, *p, *p1; + + if (size != 0) { + newlist = malloc(size); + if (newlist != NULL) { + error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, + newlist, size); + if (error > 0) { + p = newlist; + p1 = list; + while ((p - newlist) < error) { + uint8_t len = *(uint8_t *)p; + p++; + if ((p + len - newlist) > error) + break; + if (len > 0) { + bcopy(p, p1, len); + p += len; + p1 += len; + *p1++ = '\0'; + } + } + error = p1 - list; + } + free(newlist); + } + } else { + error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, + list, size); + } +#elif defined(__linux__) + error = flistxattr(fd, list, size); +#elif defined(DARWIN) + error = flistxattr(fd, list, size, 0); +#endif + + return (error); +} + +int +ceph_os_removexattr(const char *path, const char *name) +{ + int error = -1; + +#if defined(__FreeBSD__) + error = extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); +#elif defined(__linux__) + error = removexattr(path, name); +#elif defined(DARWIN) + error = removexattr(path, name, 0); + /* ENOATTR and ENODATA have different values */ + if (error < 0 && errno == ENOATTR) + errno = ENODATA; +#endif + + return (error); +} + +int +ceph_os_fremovexattr(int fd, const char *name) +{ + int error = -1; + +#if defined(__FreeBSD__) + error = extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name); +#elif defined(__linux__) + error = fremovexattr(fd, name); +#elif defined(DARWIN) + error = fremovexattr(fd, name, 0); + /* ENOATTR and ENODATA have different values */ + if (error < 0 && errno == ENOATTR) + errno = ENODATA; +#endif + + return (error); +}