--- /dev/null
- AC_DEFINE([HAVE_LAZY_SIZE_ON_MDT], 1,
- [have lazy size on MDT])
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([lipe], [m4_esyscmd(./version-gen.sh)], [lixi@ddn.com], [lipe])
+AC_CONFIG_SRCDIR(./pylipe/lipe.py)
+AC_CONFIG_HEADERS(config.h)
+
+AM_INIT_AUTOMAKE([tar-pax dist-bzip2 foreign])
+AM_EXTRA_RECURSIVE_TARGETS([check_clean])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+AC_LANG(C)
+
+AC_PREFIX_DEFAULT([/usr])
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AM_PROG_CC_C_O
+AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes")
+
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_LEX
+AC_PROG_YACC
+PKG_PROG_PKG_CONFIG
+
+#
+# MB_CHECK_FILE
+#
+# Check for file existance even when cross compiling
+# $1 - file to check
+# $2 - do 'yes'
+# $3 - do 'no'
+#
+AC_DEFUN([MB_CHECK_FILE], [
+AS_VAR_PUSHDEF([mb_file], [mb_cv_file_$1])dnl
+AC_CACHE_CHECK([for $1], mb_file, [
+AS_IF([test -r "$1"],
+ [AS_VAR_SET(mb_file, [yes])],
+ [AS_VAR_SET(mb_file, [no])])
+])
+AS_IF([test AS_VAR_GET(mb_file) = yes], [$2], [$3])[]dnl
+AS_VAR_POPDEF([mb_file])dnl
+]) # MB_CHECK_FILE
+
+#
+# MB_ARG_REPLACE_PATH(PACKAGE, PATH)
+#
+AC_DEFUN([MB_ARG_REPLACE_PATH], [
+new_configure_args=
+eval set -- $ac_configure_args
+for arg; do
+ case $arg in
+ --with-[$1]=*)
+ arg=--with-[$1]=[$2] ;;
+ *\'*)
+ arg=$(printf %s\n ["$arg"] | \
+ sed "s/'/'\\\\\\\\''/g") ;;
+ esac
+ dnl AS_VAR_APPEND([new_configure_args], [" '$arg'"])
+ new_configure_args="$new_configure_args '$arg'"
+done
+ac_configure_args=$new_configure_args
+])
+
+#
+# __MB_ARG_CANON_PATH
+#
+# this is the work-horse of the next function
+#
+AC_DEFUN([__MB_ARG_CANON_PATH], [
+ [$3]=$(readlink -f $with_$2)
+ MB_ARG_REPLACE_PATH([$1], $[$3])
+])
+
+#
+# MB_ARG_CANON_PATH
+#
+# a front-end for the above function that transforms - and . in the
+# PACKAGE portion of --with-PACKAGE into _ suitable for variable names
+#
+AC_DEFUN([MB_ARG_CANON_PATH], [
+ __MB_ARG_CANON_PATH([$1], m4_translit([$1], [-.], [__]), [$2])
+])
+
+dnl We may be able to use older versions, but I have not verified that
+PKG_CHECK_MODULES([ext2fs], [ext2fs >= 1.42.7 com_err >= 1.42.7])
+PKG_CHECK_MODULES([json_c], [json-c >= 0.11])
+PKG_CHECK_MODULES([yaml], [yaml-0.1 >= 0.1.4])
+
+AC_CHECK_HEADER([lustre/lustreapi.h], , AC_MSG_ERROR([liblustreapi is required]))
+
+AC_CHECK_HEADER([linux/lustre/lustre_user.h],
+ [new_user_header=yes],)
+
+AC_CHECK_HEADER([lustre/lustre_user.h],
+ [idle_user_header=yes],)
+
+if test "x$new_user_header" = "x" -a "x$idle_user_header" = "x"; then
+ AC_MSG_ERROR([lustre_user.h is required])
+fi
+
+if test "x$new_user_header" = "xyes"; then
+ AC_DEFINE(NEW_USER_HEADER, 1, [Lustre uses new user header])
+fi
+
+if test "x$idle_user_header" = "xyes"; then
+ AC_DEFINE(IDLE_USER_HEADER, 1, [Lustre uses idle user header])
+fi
+
+# few defines which aren't conditional anymore
+AC_DEFINE([HAVE_LUSTRE_PFL], 1,
+ [Lustre has PFL support])
+AC_DEFINE([HAVE_LAYOUT_BY_XATTR], 1,
+ [have llapi_layout_get_by_xattr()])
+
+# -------- check for llapi_changelog_in_buf() --------
+AC_MSG_CHECKING([Lustre have llapi_changelog_in_buf()])
+saved_libs=$LIBS
+LIBS="-llustreapi -llnetconfig"
+AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #include <lustre/lustreapi.h>
+
+ int main(void) {
+ llapi_changelog_in_buf(NULL);
+ }
+])],[have_llapi_changelog_in_buf=yes
+], [have_llapi_changelog_in_buf="no"])
+LIBS=$saved_libs
+AC_MSG_RESULT([$have_llapi_changelog_in_buf])
+AM_CONDITIONAL([BUILD_HOTPOOL_UTILS], [test x$have_llapi_changelog_in_buf = xyes])
+
+# -------- check for build laudit --------
+BUILD_LAUDIT="yes"
+NIDSTR=""
+AC_CHECK_HEADER([lnet/nidstr.h], NIDSTR="lnet", [], [
+AC_INCLUDES_DEFAULT
+#include <stdbool.h>
+])
+AS_IF([test "x$NIDSTR" = "xlnet" ],
+ [AC_DEFINE([HAVE_LNET_NIDSTR], [1], [lnet/nidstr.h exists]) lustre_user_dir="lustre"],
+ [AC_CHECK_HEADER([linux/lnet/nidstr.h], NIDSTR="linux", [], [
+AC_INCLUDES_DEFAULT
+#include <stdbool.h>
+])])
+AS_IF([test "x$NIDSTR" = "xlinux" ],
+ [AC_DEFINE([HAVE_LINUX_NIDSTR], [1], [linux/lnet/nidstr.h exists])] lustre_user_dir="linux/lustre")
+if test "x$NIDSTR" = "x"; then
+ AC_MSG_WARN([])
+ AC_MSG_WARN([nidstr include is needed for laudit. laudit will not be built.])
+ AC_MSG_WARN([])
+ BUILD_LAUDIT="no"
+fi
+
+if test "x$BUILD_LAUDIT" = "xyes"; then
+AC_MSG_CHECKING([whether Lustre is audit-capable])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+ #include <$lustre_user_dir/lustre_user.h>
+
+ int main(void) {
+ enum changelog_rec_type type1 = CL_GETXATTR;
+ enum changelog_rec_type type2 = CL_DN_OPEN;
+ }
+])],[audit_capable="yes"],[audit_capable="no"])
+AC_MSG_RESULT([$audit_capable])
+if test "x$audit_capable" = "xno"; then
+ AC_MSG_WARN([])
+ AC_MSG_WARN([Lustre must be audit-capable for laudit. laudit will not be built.])
+ AC_MSG_WARN([])
+ BUILD_LAUDIT="no"
+fi
+fi
+
+AC_SUBST(BUILD_LAUDIT)
+AM_CONDITIONAL(BUILD_LAUDIT, test "$BUILD_LAUDIT" = "yes")
+
+# -------- check for distro version --------
+AC_MSG_CHECKING([for distro version])
+DISTRO=$(sh detect-distro.sh)
+DISTRO_NAME=$(echo $DISTRO | awk -F '-' '{print $1}')
+if [[[ "$DISTRO_NAME" != "rhel" && "$DISTRO_NAME" != "fc" ]]]; then
+ AC_MSG_ERROR([$DISTRO_NAME is not a supported distro.])
+fi
+DISTRO_RELEASE=$(echo $DISTRO | awk -F 'rhel-' '{print $2}' | awk -F '.' '{print $1}')
+AC_MSG_RESULT([$DISTRO_RELEASE])
+AC_SUBST(DISTRO_RELEASE)
+
+# ------- check for python --------
+AC_CHECK_PROGS([PYTHON], [python2.7], [])
+if test "x$PYTHON" = "x"; then
+ AC_MSG_ERROR([Python is needed for tests. Install python please.])
+fi
+
+# ------- check for pylint --------
+AC_CHECK_PROGS([PYLINT], [pylint-2.7], [])
+if test "x$PYLINT" = "x"; then
+ AC_MSG_ERROR([pylint-2.7 is needed to check python coding style. Install pylint please.])
+fi
+
+# ------- check for libssh --------
+AC_CHECK_LIB([ssh], [ssh_new], [
+ AC_CHECK_HEADER([libssh/libssh.h], [], [
+ AC_MSG_ERROR([libssh/libssh.h is needed for lpurge. Install libssh please.])])
+ ], [
+ AC_MSG_ERROR([
+libssh library is needed for lpurge. Install libssh please.])
+])
+
+PKG_CHECK_MODULES([libssh_threads], [libssh_threads],
+ [have_lssh_threads=yes],
+ [have_lssh_threads=no],
+)
+AM_CONDITIONAL([HAVE_SSH_THREADS], [test x$have_lssh_threads = xyes])
+
+# -------- check whether enable zfs support --------
+AC_MSG_CHECKING([whether enable zfs support])
+AC_ARG_ENABLE([zfs],
+ AC_HELP_STRING([--enable-zfs],
+ [enable zfs support]),
+ [], [enable_zfs="no"])
+AC_MSG_RESULT([$enable_zfs])
+AM_CONDITIONAL([ZFS], [test x$enable_zfs = xyes])
+
+AS_IF([test "x$enable_zfs" = xyes ], [
+ PKG_CHECK_MODULES([zfs], [libzfs], AC_DEFINE(HAVE_ZFS, 1, [enable ZFS support]))
+
+ saved_libs=$LIBS
+ LIBS="-lzfs -lzpool -I/usr/include/libspl -I/usr/include/libzfs"
+
+ AC_MSG_CHECKING([libzutil.h exists])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <libzfs/libzutil.h>
+ int main(void) {
+ }
+ ])],[have_libzfs_libzutil_h=yes
+ ], [have_libzfs_libzutil_h="no"])
+ AC_MSG_RESULT([$have_libzfs_libzutil_h])
+ AS_IF([test "x$have_libzfs_libzutil_h" = xyes ],
+ [AC_DEFINE(HAVE_LIBZFS_LIBZUTIL_H, 1, [have the <libzfs/libzutil.h> header file])])
+
+ AC_MSG_CHECKING([ZFS has special kthread_t])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <sys/zfs_context.h>
+
+ int main(void) {
+ kthread_t kt;
+ kt.t_func = NULL;
+ }
+ ])],[have_zfs_special_kthread_t=yes
+ ], [have_zfs_special_kthread_t="no"])
+ AC_MSG_RESULT([$have_zfs_special_kthread_t])
+ AS_IF([test "x$have_zfs_special_kthread_t" = xyes ],
+ [AC_DEFINE(HAVE_ZFS_SPECIAL_KTHREAD_T, 1, [ZFS has special kthread_t])])
+
+ AC_MSG_CHECKING([ZFS has ZPL_PROJID])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <sys/sa.h>
+ #include <sys/zfs_acl.h>
+ #include <sys/zfs_sa.h>
+
+ int main(void) {
+ int attr = ZPL_PROJID;
+ }
+ ])],[have_zfs_zpl_projid=yes
+ ], [have_zfs_zpl_projid="no"])
+ AC_MSG_RESULT([$have_zfs_zpl_projid])
+ AS_IF([test "x$have_zfs_zpl_projid" = xyes ],
+ [AC_DEFINE(HAVE_ZFS_ZPL_PROJID, 1, [ZFS has ZPL_PROJID])])
+
+ LIBS=$saved_libs
+])
+
+# -------- check whether enable LPCC support for copytool --------
+AC_MSG_CHECKING([whether enable LPCC support for copytool])
+AC_ARG_ENABLE([copytool-lpcc],
+ AC_HELP_STRING([--enable-copytool-lpcc],
+ [enable LPCC support for copytool]),
+ [], [enable_copytool_lpcc="no"])
+AC_MSG_RESULT([$enable_copytool_lpcc])
+AM_CONDITIONAL([COPYTOOL_LPCC], [test x$enable_copytool_lpcc = xyes])
+AS_IF([test "x$enable_copytool_lpcc" = xyes ],
+ [AC_DEFINE([HAVE_COPYTOOL_LPCC], [1], [enable LPCC support for copytool])])
+
+# -------- check for cached ISO --------
+AC_MSG_CHECKING([for cached ISO])
+AC_ARG_WITH([cached-iso],
+ AC_HELP_STRING([--with-cached-iso=path],
+ [set path to cached ISO]),
+ [MB_ARG_CANON_PATH([cached-iso], [CACHED_ISO_PATH])],
+ [])
+AC_MSG_RESULT([$CACHED_ISO_PATH])
+AC_SUBST(CACHED_ISO_PATH)
+
+AS_IF([test "x$CACHED_ISO_PATH" != "x"],
+ [MB_CHECK_FILE([$CACHED_ISO_PATH], [],
+ [AC_MSG_ERROR([cached ISO dir $CACHED_ISO_PATH could not be found.])])])
+
+dnl Pull the needed libraries into LIBS (needed for the AC_LINK_IFELSE below)
+dnl These should never fail if the PKG_CHECK above passes
+AC_SEARCH_LIBS([com_err], [com_err])
+AC_SEARCH_LIBS([ext2fs_open2], [ext2fs])
+
+LIPE_RELEASE="1"
+AC_DEFINE_UNQUOTED(RELEASE, "$LIPE_RELEASE", [release info] )
+AC_DEFINE_UNQUOTED(LIPE_RELEASE, "$LIPE_RELEASE", [release info] )
+AC_SUBST(LIPE_RELEASE)
+
+AC_MSG_CHECKING([for lipe revision])
+LIPE_REVISION=$(bash lipe-revision.sh)
+AC_MSG_RESULT([$LIPE_REVISION])
+AC_DEFINE_UNQUOTED(LIPE_REVISION, "$LIPE_REVISION", [revision info] )
+AC_SUBST(LIPE_REVISION)
+
+# for exporting to spec file
+AC_SUBST(ac_configure_args)
+AC_CONFIG_FILES([Makefile
+ lipe.spec
+ src/Makefile
+ pybuild/Makefile
+ pylipe/Makefile])
+AC_OUTPUT
--- /dev/null
- #ifdef HAVE_LAZY_SIZE_ON_MDT
+/*
+ * Copyright (c) 2019, DDN Storage Corporation.
+ */
+/*
+ *
+ * Get the EAs from POSIX file system
+ *
+ * Author: Li Xi <lixi@ddn.com>
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <attr/xattr.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include "fake_lustre_idl.h"
+#include "lipe_object_attrs.h"
+#include "lustre_ea.h"
+#include "posix_ea.h"
+#include "debug.h"
+#include "policy.h"
+#include "misc.h"
+
+static int get_link_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ int rc;
+ ssize_t size;
+ const char *path = object->u.lo_posix.lop_path;
+
+ size = lgetxattr(path, XATTR_NAME_LINK, attrs->loa_leh_buf,
+ sizeof(attrs->loa_leh_buf));
+ if (size < 0) {
+ if (errno == ENOATTR)
+ LDEBUG("path [%s] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_LINK);
+ else
+ LDEBUG("failed to get [%s] xattr of path [%d]: %s, ignoring\n",
+ XATTR_NAME_LINK, path, strerror(errno));
+ return -errno;
+ }
+
+ rc = lipe_object_attrs_set_links(attrs, attrs->loa_leh_buf, size);
+ if (rc) {
+ LERROR("failed to decode linkea for path [%s]\n", path);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_lmv_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ ssize_t rc;
+ const char *path = object->u.lo_posix.lop_path;
+
+ memset(attrs->loa_lmv_buf, 0, sizeof(attrs->loa_lmv_buf));
+
+ rc = lgetxattr(path, XATTR_NAME_LMV, attrs->loa_lmv_buf,
+ sizeof(attrs->loa_lmv_buf));
+ if (rc < 0) {
+ if (errno == ENOATTR) {
+ LDEBUG("path [%s] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_LMV);
+ return 1;
+ } else {
+ LDEBUG("failed to get [%s] xattr of path [%d]: %s, ignoring\n",
+ XATTR_NAME_LMV, path, strerror(errno));
+ return -errno;
+ }
+ }
+
+ return 0;
+}
+
+static int get_lma_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ char buf[MAX_LINKEA_SIZE];
+ struct lustre_mdt_attrs *lma;
+ ssize_t size;
+ const char *path = object->u.lo_posix.lop_path;
+
+ size = lgetxattr(path, XATTR_NAME_LMA, buf,
+ MAX_LINKEA_SIZE);
+ if (size < 0) {
+ if (errno == ENOATTR)
+ LDEBUG("path [%d] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_LMA);
+ else
+ LDEBUG("failed to get [%s] xattr of path [%d]: %s, ignoring\n",
+ XATTR_NAME_LMA, path, strerror(errno));
+ return -errno;
+ }
+
+ lma = (struct lustre_mdt_attrs *)buf;
+ fid_le_to_cpu(&attrs->loa_fid, &lma->lma_self_fid);
+ snprintf(attrs->loa_fid_str, sizeof(attrs->loa_fid_str), DFID_NOBRACE,
+ PFID(&attrs->loa_fid));
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LMAEA;
+ return 0;
+}
+
+static int get_hsm_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ char buf[MAX_LINKEA_SIZE];
+ struct hsm_attrs *hsm;
+ int rc;
+ int size;
+ struct hsm_user_state *hus = &attrs->loa_hsm_state;
+ const char *path = object->u.lo_posix.lop_path;
+
+ LASSERT(sizeof(*hsm) < MAX_LINKEA_SIZE);
+ size = lgetxattr(path, XATTR_NAME_HSM, buf,
+ MAX_LINKEA_SIZE);
+ if (size < 0) {
+ if (errno == ENOATTR) {
+ LDEBUGW(&attrs->loa_fid,
+ "path [%d] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_HSM);
+ hus->hus_states = 0;
+ hus->hus_archive_id = 0;
+ } else {
+ LDEBUG("failed to get [%s] xattr of path [%s]: %s, ignoring\n",
+ XATTR_NAME_HSM, path, strerror(errno));
+ return -errno;
+ }
+ } else {
+ hsm = (struct hsm_attrs *)buf;
+ rc = lustre_hsm2user(hsm, hus);
+ if (rc) {
+ LERROR("failed to extract [%s] xattr for path [%s], rc = %d\n",
+ XATTR_NAME_HSM, path, rc);
+ return rc;
+ }
+ }
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_HSMEA;
+ return 0;
+}
+
+static int get_lum_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ int rc;
+ int size;
+ struct lov_user_md *lov = attrs->loa_lum;
+ const char *path = object->u.lo_posix.lop_path;
+
+ size = lgetxattr(path, XATTR_NAME_LOV,
+ (char *)lov, attrs->loa_lum_size);
+ if (size < 0) {
+ if (errno == ENOATTR)
+ LDEBUG("path [%d] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_LMA);
+ else
+ LDEBUG("failed to get [%s] xattr of path [%s]: %s, ignoring\n",
+ XATTR_NAME_LMA, path, strerror(errno));
+ return -errno;
+ }
+
+ rc = decode_lum(lov, size);
+ if (rc) {
+ LERROR("failed to decode lovea for path [%s]\n", path);
+ return rc;
+ }
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_LOVEA;
+ return 0;
+}
+
- attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_SOM;
+/*
+ * llapi_layout_get_by_xattr() and LSoM are both included in Lustre-2.12,
+ * so no need to duplicate the macros.
+ */
+static int get_som_ea_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ int size;
+ struct lustre_som_attrs *som = &attrs->loa_som;
+ const char *path = object->u.lo_posix.lop_path;
+
+ size = lgetxattr(path, XATTR_NAME_SOM,
+ (char *)som, sizeof(*som));
+ if (size < 0) {
+ if (errno == ENOATTR)
+ LDEBUG("path [%d] has no [%s] xattr, ignoring\n",
+ path, XATTR_NAME_LMA);
+ else
+ LDEBUG("failed to get [%s] xattr of path [%s]: %s, ignoring\n",
+ XATTR_NAME_LMA, path, strerror(errno));
+ return -errno;
+ }
+
+ if (size != sizeof(*som)) {
+ LERROR("unexpected size of [%s] xattr for path [%s], expected [%d], got [%d]\n",
+ XATTR_NAME_SOM, path, sizeof(*som), size);
+ return -ENODATA;
+ }
+
+ lustre_som_swab(som);
- #endif /* HAVE_LAZY_SIZE_ON_MDT */
++
+ return 0;
+}
- #ifdef HAVE_LAZY_SIZE_ON_MDT
+
+static int check_dir_empty_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ DIR *d;
+ struct dirent64 *dent;
+ bool is_empty = true;
+ const char *path = object->u.lo_posix.lop_path;
+
+ d = opendir(path);
+ if (d == NULL) {
+ LDEBUG("failed to opendir [%s]: %s\n", path, strerror(errno));
+ return -errno;
+ }
+
+ while ((dent = readdir64(d)) != NULL) {
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+ continue;
+ is_empty = false;
+ break;
+ }
+ closedir(d);
+
+ attrs->loa_is_empty = is_empty;
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_EMPTY;
+ return 0;
+}
+
+static int get_dir_entries_posix(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ DIR *d;
+ struct dirent64 *dent;
+ int64_t entry_number = 0;
+ const char *path = object->u.lo_posix.lop_path;
+
+ d = opendir(path);
+ if (d == NULL) {
+ LDEBUG("failed to opendir [%s]: %s\n", path, strerror(errno));
+ return -errno;
+ }
+
+ while ((dent = readdir64(d)) != NULL) {
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+ continue;
+ entry_number++;
+ }
+ closedir(d);
+
+ attrs->loa_entries = entry_number;
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_ENTRIES;
+
+ attrs->loa_is_empty = (entry_number == 0);
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_EMPTY;
+ return 0;
+}
+
+void print_object_prefix_posix(struct lipe_object *object, int level)
+{
+ _lipe_logging(level, false, "path [%s], ", object->u.lo_posix.lop_path);
+}
+
+static int posix_get_xattr(struct lipe_object *object,
+ struct lipe_object_attrs *attrs, const char *path,
+ const char *name)
+{
+ int rc;
+ char *value;
+ size_t value_len;
+ struct lipe_xattr *xattr;
+
+ rc = get_xattr_value(path, name, &value, &value_len);
+ if (rc) {
+ OBJ_ERROR(object, "failed to get value for xattr [%s]\n",
+ name);
+ return rc;
+ }
+
+ LIPE_ALLOC_PTR(xattr);
+ if (xattr == NULL) {
+ OBJ_ERROR(object, "not enough memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ xattr->lx_name = strdup(name);
+ if (xattr->lx_name == NULL) {
+ OBJ_ERROR(object, "not enough memory\n");
+ rc = -ENOMEM;
+ goto out_xattr;
+ }
+ xattr->lx_value = value;
+ xattr->lx_value_len = value_len;
+ lipe_list_add_tail(&xattr->lx_linkage, &attrs->loa_xattrs);
+ return 0;
+out_xattr:
+ LIPE_FREE_PTR(xattr);
+out:
+ free(value);
+ return rc;
+}
+
+static int posix_get_all_xattrs(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ int rc;
+ char *name;
+ size_t namelen;
+ char *xattr_list;
+ ssize_t list_size;
+ const char *path = object->u.lo_posix.lop_path;
+
+ rc = get_xattr_list(path, &xattr_list, &list_size);
+ if (rc) {
+ OBJ_ERROR(object, "failed to get xattr list\n");
+ return rc;
+ }
+
+ name = xattr_list;
+ while (name < xattr_list + list_size) {
+ rc = posix_get_xattr(object, attrs, path, name);
+ if (rc) {
+ OBJ_ERROR(object, "failed to get xattr of [%s]\n",
+ name);
+ goto out;
+ }
+ namelen = strlen(name) + 1;
+ name += namelen;
+ }
+
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_ALL_XATTR;
+out:
+ free(xattr_list);
+ return rc;
+}
+
+static int posix_get_projid(struct lipe_object *object,
+ struct lipe_object_attrs *attrs)
+{
+ int fd;
+ int rc;
+ struct fsxattr fsx;
+ const char *path = object->u.lo_posix.lop_path;
+
+ LASSERT(attrs->loa_attr_bits & LIPE_OBJECT_ATTR_ATTR);
+ if (!S_ISREG(attrs->loa_mode) && !S_ISDIR(attrs->loa_mode)) {
+ attrs->loa_projid = 0;
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_PROJID;
+ return 0;
+ }
+
+ fd = open(path, O_RDONLY | O_NOCTTY | O_NDELAY);
+ if (fd < 0) {
+ OBJ_ERROR(object, "failed to open file: %s\n",
+ strerror(errno));
+ return -errno;
+ }
+
+#if defined(FS_IOC_FSGETXATTR)
+ rc = ioctl(fd, FS_IOC_FSGETXATTR, &fsx);
+#elif defined(LL_IOC_FSGETXATTR)
+ rc = ioctl(fd, LL_IOC_FSGETXATTR, &fsx);
+#else
+#error IOC_FSGETXATTR is not defined
+#endif
+ rc = 0;
+ if (rc) {
+ OBJ_ERROR(object, "failed to ioctl fsgetxattr: %s\n",
+ strerror(errno));
+ rc = -errno;
+ goto out;
+ }
+ attrs->loa_projid = fsx.fsx_projid;
+ attrs->loa_attr_bits |= LIPE_OBJECT_ATTR_PROJID;
+out:
+ close(fd);
+ return rc;
+}
+
+struct lipe_backfs_operations posix_operations = {
+ .print_object_prefix = print_object_prefix_posix,
+ .get_lma_ea = get_lma_ea_posix,
+ .get_link_ea = get_link_ea_posix,
+ .get_lmv_ea = get_lmv_ea_posix,
+ .get_hsm_ea = get_hsm_ea_posix,
+ .get_lum_ea = get_lum_ea_posix,
- #endif
+ .get_som_ea = get_som_ea_posix,
+ .check_dir_empty = check_dir_empty_posix,
+ .get_dir_entries = get_dir_entries_posix,
+ .get_all_xattrs = posix_get_all_xattrs,
+ .get_projid = posix_get_projid,
+};